SysDesignPrep.com
Interactive concepts

Sticky sessions vs a shared session store vs JWTs: an interactive simulator

Once a user logs in, every later request has to say who they are. The session can live in the memory of the server that logged them in, with the load balancer pinning the user there (sticky sessions); in a shared store such as Redis that every server reads; or in a signed token such as a JWT that the client sends back and any server can verify. Each one fails in a different place.

The playground runs the same fleet through five events in order. Step through them and watch which approach loses sessions, which one stops serving, and which one cannot take a session back.

The fleet scales out to 6 servers and 120 more users log in. Sticky sessions keep the first four servers at 100 users each while the new ones get 60, so the busiest server carries 15% more than the average. With a shared store or tokens every server takes 86 or 87 at once.

Sticky sessionsin server memory; each user pinned to one server
100S1
100S2
100S3
100S4
60S5
60S6
Load balanceruser pinned by cookie

The users already logged in stay pinned to the first four servers; the new ones only get the 120 users who log in after the scale-out.

Logged out
0
Failing now
0
Revoke a session
next request
Per request
none, in memory
Shared session storein Redis; any server can serve any user
87S1
87S2
87S3
87S4
86S5
86S6
Redisevery request reads it

The two new servers take a fair share of requests at once, because any server can serve any user.

Logged out
0
Failing now
0
Revoke a session
next request
Per request
about 1 ms to Redis
Signed token (JWT)in the cookie; servers only check the signature
87S1
87S2
87S3
87S4
86S5
86S6
Cookie800 B, signed

The two new servers take a fair share of requests at once, because any server can serve any user.

Logged out
0
Failing now
0
Revoke a session
at expiry
Per request
about 0.05 ms of CPU
users served by the serversessions wiped by a restartrequests failingserver not running yet

What each approach costs

  • Sticky sessions need no extra infrastructure and no lookup, but the server is no longer disposable. Scaling out from 4 to 6 servers leaves the existing users where they are, so the old servers keep 100 users each while the new ones get 60. A restart for a deploy logs out every user on that server, here 100 of them, and afterwards the busiest server carries 43% more than the average.
  • A shared session store makes the web servers stateless: new servers take a fair share at once and restarts lose nothing. The price is a network lookup on every request and a dependency on the store. If it is down, nobody can be authenticated: here all 520 users fail for the 30 s it takes to promote a replica.
  • A signed token needs no lookup at all, only a signature check, and survives both the restart and the store outage. But the server cannot forget a token it has signed. A stolen token works until it expires, up to 60 minutes here, and so does a token for a user who was just banned or whose role changed. Tokens are also bigger: about 800 bytes on every request instead of a 40-byte session ID.

What real systems do

  • Short access tokens with refresh tokens. An access token valid for 5 to 15 minutes is verified without a lookup; the long-lived refresh token is checked against a store when it is exchanged, so revoking it takes effect within minutes.
  • Make the store highly available. A Redis primary with replicas and automatic failover, with sessions spread across shards, means one failed node stalls a fraction of users for seconds rather than everyone.
  • Use stickiness as an optimization, not for correctness. Pinning users to a server can keep caches warm, but if losing the pin only costs a cache miss, servers stay disposable.
  • Drain before restarting. If sessions do live on servers, stop sending new users to a server and wait for its sessions to end before a deploy.

The two designs on the wire

# shared session store: the cookie is only an ID
Set-Cookie: sid=9f2c7e41a0; HttpOnly; Secure; SameSite=Lax
GET sess:9f2c7e41a0 -> {user: 812, roles: [buyer], exp: ...}   # Redis, every request
DEL sess:9f2c7e41a0                                            # logout or revoke: gone at once

# signed token: the cookie is the session
Set-Cookie: at=eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiI4MTIiLCJleHAiOjE3...; HttpOnly; Secure
verify(signature, public_key) and exp > now                    # no lookup
# revoke: wait for exp, or check a deny list of token IDs (a lookup again)
# common middle ground: a 5 to 15 minute access token plus a refresh token checked in a store

In a system design interview

When the design has logged-in users, say where the session lives: “Web servers are stateless. The client holds a short-lived signed access token, which every service can verify locally, and a refresh token that the auth service checks in Redis, so logout and bans take effect within the access token’s lifetime. No sticky sessions, so we can autoscale and deploy without logging anyone out.” Expect the follow-ups: how to revoke a token immediately, what happens when the store is down, and how WebSocket connections, which are sticky by nature, fit in.

Read the guide to JWTs vs session cookies or stateful vs stateless services, see load balancing algorithms, or watch a strong candidate design a URL shortener.

Questions people ask

What are sticky sessions?

A load balancer setting, also called session affinity, that sends every request from a user to the same backend server, usually by a cookie or a hash of the client address. It lets that server keep the user’s session in memory, at the cost of uneven load and sessions lost when the server restarts.

Why are sticky sessions considered bad for scaling?

Existing users stay pinned to the servers they started on, so new servers only receive new users and load stays uneven after a scale-out. A crash or a deploy logs out everyone on that server, and servers cannot be removed without draining them first.

What is a shared session store?

A fast database, typically Redis or Memcached, that holds session data keyed by a random session ID kept in a cookie. Every web server looks the session up on each request, so any server can serve any user and the servers themselves stay stateless.

Should I use JWTs or server-side sessions?

Server-side sessions are simple and can be revoked instantly, at the cost of a lookup per request. JWTs avoid the lookup and suit many services verifying identity independently, but they cannot be revoked before they expire without a deny list. Many systems combine both: short-lived JWT access tokens and a refresh token checked in a store.

How do you revoke a JWT?

Keep access tokens short-lived, 5 to 15 minutes, so a revoked refresh token stops new ones from being issued. For immediate revocation, servers check the token’s ID against a deny list, which brings back a shared lookup, though only for revoked tokens and often cached.

What happens if the session store goes down?

With sessions only in the store, no request can be authenticated, so every logged-in user gets errors or is logged out until it recovers. Run it with replicas and automatic failover, shard it so one node affects only part of the users, and keep its latency and availability on the critical path dashboards.

Are WebSocket connections sticky?

Yes, by nature: a WebSocket stays open to one server. Designs keep per-connection state there but put the session itself in a store or a token, so a reconnecting client can land on any server and continue.