Session management flow
User sessions from login through expiry and refresh.
Sessions are the bridge between authentication (proving who you are once) and application usage (staying logged in across requests). This diagram shows the complete lifecycle: login creating a session and storing it server-side, every request carrying the session ID in a cookie, the server validating it, and the timeout that logs you out when you're idle.
The key insight is separation: the browser just remembers the session ID and sends it; the server holds the truth about that session (user_id, expiry, permissions) in a dedicated store, so the server can revoke a session instantly and scale across load-balanced machines.
When to use this template
- Security design review — walk through where sessions are stored, how long they live, and what happens at expiry before you build authentication.
- Debugging "session disappeared" bugs — annotate each arrow with your actual timeouts and storage mechanism so the team can see where the assumption is wrong.
- Onboarding new backend engineers — show why we don't just store user_id in the JWT and trust it; show why we need a server-side store.
How to adapt it
Customize it for your architecture and session strategy:
- Replace SessionStore with your real backend (Redis, Memcache, database, or stateless JWT).
- Add a refresh-token exchange after the 401 if users stay logged in across browser restarts.
- Insert a session validation cache between Server and SessionStore if you want to optimize repeated lookups within a request.
- Add a concurrent session limit check during login if your product only allows one active session per user.
Visual edits regenerate clean Mermaid code, so you can edit message labels (timeouts, storage backend names) without syntax friction — ideal for documenting the exact flow your team implements.
Mermaid code
Copy it anywhere Mermaid is supported — GitHub, Notion, or your docs.
sequenceDiagram
actor User
participant Browser
participant Server
participant SessionStore
User->>Browser: Log in with credentials
Browser->>Server: POST /login (username, password)
Server->>SessionStore: Create session, store user_id
SessionStore-->>Server: session_id
Server-->>Browser: Set-Cookie: session_id
Browser->>Server: GET /dashboard (with session_id cookie)
Server->>SessionStore: Lookup session_id
SessionStore-->>Server: user_id + expiry
Server-->>Browser: Dashboard (200 OK)
Note over Browser,SessionStore: Session expires after idle timeout
Browser->>Server: GET /profile (with expired session_id)
Server->>SessionStore: Lookup session_id
SessionStore-->>Server: Not found
Server-->>Browser: Redirect to /login (401)
Frequently asked questions
- What is a session and how does it differ from authentication?
- Authentication proves who you are (you log in with a password); a session is the proof of that authentication that persists across requests. After you authenticate, the server creates a session and gives your browser a session ID (usually in a cookie). On every request, your browser sends that session ID so the server knows you're the same person without asking for your password again.
- Why does the server store sessions in a separate system?
- So the server can forget you when your session expires or you log out, making it stateful security — once you log out, that session ID is gone and invalid. This prevents session hijacking: if someone steals your old session ID after you logged out, the server won't recognize it. A separate SessionStore (Redis, Memcache, database) keeps memory efficient and allows load balancers to route you to any server (all servers can look up your session).
- What is the difference between session timeout and session refresh?
- Session timeout is automatic expiry: your session exists for N minutes of activity or absolute age, then dies. Session refresh extends the expiry when you're actively using the app — slide a timeout window forward on each request so idle users log out but active users stay signed in. Both show in this diagram: the idle timeout causes the 401, and you'd refresh by requesting a new session after successful re-login.
- How do I add session persistence across browser restarts?
- Use a 'Remember me' token: on login, generate a long-lived refresh token (stored in a persistent, httpOnly cookie) alongside the short-lived session ID. When the session expires, check for a refresh token and issue a new session silently without showing the login page. Add a second exchange after the 401 to show that flow.