Command Palette

Search for a command to run...

Hectal
PHASE 8Intermediate ~9 min· topic 4 of 6

Topic 8.4

Distributed Session Management

In one line

Storing sessions in Redis makes app servers stateless: any instance can serve any user, deployments don't log people out, and you can revoke sessions centrally. Design for TTL, logout everywhere, session fixation, concurrent device limits, and what happens when Redis fails.

0/6 · 0%

Think of it like this

A hotel that keeps guest records at the front desk instead of in each room's drawer. Guests can switch rooms, any receptionist can help them, and if a key card is stolen, the desk can cancel all of that guest's cards at once.

Key ideas

  1. 01

    Architecture: browser → load balancer → any app instance → Redis session store. No sticky sessions needed, so scaling and rolling deploys are easy.

  2. 02

    Data: session:{id} as a hash (user ID, roles, created, last seen, device) with an idle TTL, plus an absolute lifetime field. Session IDs must be long random values (at least 128 bits) sent in HttpOnly, Secure, SameSite cookies.

  3. 03

    Logout everywhere: a per-user index set user:{id}:sessions; to revoke, delete every session key in it. Spring Session keeps a similar principal-name index when using the indexed repository.

  4. 04

    Session fixation: always create a new session ID at login (and on privilege changes), deleting the pre-login session, so an attacker can't plant a known session ID on a victim.

  5. 05

    Concurrency and devices: limit active sessions per user by checking SCARD on the index at login and removing the oldest (keep a sorted set by login time instead of a set if order matters).

  6. 06

    Failure behaviour: if Redis is lost, everyone is logged out. Decide if that's acceptable; if not, use replicas with automatic failover and AOF. JWTs are an alternative for stateless auth but make revocation harder (you end up keeping a denylist in Redis anyway).

Code & diagrams

sessions.mermaiddiagram
Rendering diagram…
logout-everywhere.lualua

Works when the index and sessions share a slot (standalone or a per-user hash tag); in Cluster without tags, delete per key in a pipeline.

-- KEYS[1] = user:{42}:sessions ; session keys are {42}:session:<id>
local ids = redis.call('SMEMBERS', KEYS[1])
for _, id in ipairs(ids) do
  redis.call('UNLINK', '{' .. ARGV[1] .. '}:session:' .. id)
end
redis.call('UNLINK', KEYS[1])
return #ids
SessionConfig.javajava
@Configuration
@EnableRedisIndexedHttpSession(maxInactiveIntervalInSeconds = 1800, redisNamespace = "app:session")
public class SessionConfig { }

// Log out all sessions of the current user:
@Autowired FindByIndexNameSessionRepository<? extends Session> sessions;

public void logoutEverywhere(String username) {
    sessions.findByPrincipalName(username).keySet().forEach(sessions::deleteById);
}

Interview problem

The problem

Sessions for 100M users across many app servers

Design session management for an app with 100M registered users, 20M concurrent sessions, multiple devices per user, "log out all devices", a maximum of 5 devices, and zero forced logouts during deployments.

You're given

  • 20M concurrent sessions
  • Up to 5 devices per user
  • Idle timeout 30 min, max lifetime 7 days
  • Logout everywhere

The interviewer follows up

01

Sessions in Redis or JWTs?

When it breaks

Session index sets without TTL or cleanup

What you see

Expired session IDs pile up in user:{id}:sessions forever; device limits count ghosts and users get logged out of real devices.

Fix & prevent

Remove stale IDs lazily (check EXISTS when reading the index) and set a TTL on the index at least as long as the maximum session lifetime.

Explain it without notes

01

What is session fixation, and how does rotating the session ID at login prevent it?

Practice

01

Implement a 3-device limit with a sorted set and test logging in from 4 "devices".

Trade-offs

  • ↔

    Redis sessions are revocable and simple, at the cost of a lookup per request and a dependency on Redis availability.

Done when you can

  • I can design stateless session storage with TTLs, device limits and logout everywhere.

  • I rotate session IDs at login and understand the failure impact of losing Redis.