Project: Session Sharing With Redis

Introduction

When you run multiple app instances behind a load balancer, in-memory sessions break—user logs in on server A, next request hits server B. Redis stores session data centrally so every instance reads the same state. This chapter outlines Spring Session + Redis for Java teams and the same concept for Python/Flask/FastAPI stacks, with logout and TTL policies.

Prerequisites

Problem Diagram

text
  Browser ──► LB ──► App instance 1  ──┐
              │                        ├──► Redis (shared sessions)
              └──► App instance 2  ──┘

Without Redis, each JVM/Python process holds its own session map.

Spring Session + Redis (Main Path)

Dependencies

xml
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Configuration

application.yml:

yaml
spring:
  data:
    redis:
      host: localhost
      port: 6379
  session:
    store-type: redis
    timeout: 30m

Enable:

java
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)
public class SessionConfig {
}

Code explanation:

  • Session id stays in cookie; session attributes live in Redis
  • maxInactiveIntervalInSeconds aligns with Redis TTL refresh on access

Login Flow

Standard Spring Security login—session creation is automatic. Redis keys like:

text
spring:session:sessions:<session-id>

Inspect (dev only):

bash
redis-cli KEYS "spring:session:*"
TTL spring:session:sessions:...

Session Expiration and Refresh

PolicyBehavior
Idle timeoutNo requests for 30m → session expires
Absolute maxForce re-login after 8h regardless of activity (custom filter)
Remember-meLonger-lived token separate from session cookie

Sliding expiration: Spring Session updates TTL on each request when configured.

Logout and Session Cleanup

java
// Spring Security logout handler clears SecurityContext
// Spring Session deletes Redis key for session id

Ensure /logout invalidates server session—not only client cookie delete.

For JWT-only APIs (FastAPI JWT), Redis session sharing is usually not used—stateless tokens instead.

Python Stacks (Concept)

StackApproach
FlaskFlask-Session with SESSION_TYPE=redis
FastAPICookie session middleware + Redis backend, or JWT without shared session

Flask example config:

python
app.config["SESSION_TYPE"] = "redis"
app.config["SESSION_REDIS"] = redis.from_url("redis://localhost:6379/1")

See Flask sessions.

Single Sign-On (Concept)

SSO across different apps needs shared identity provider (OAuth2/OIDC)—not just Redis session keys. Redis session sharing solves horizontal scale of one app, not full SSO across unrelated domains.

Security Checklist

  • HttpOnly, Secure, SameSite on session cookie
  • Redis requirepass and network isolation
  • No sensitive data in session without encryption
  • Session fixation protection (Spring Security default on login)

See Redis troubleshooting and FastAPI security.

Verification Checklist

  • Login on instance 1; refresh through LB still authenticated
  • Restart one app instance; session survives
  • Logout clears Redis session key
  • TTL matches configured timeout

FAQ

Sticky sessions instead of Redis?

Sticky LB works until instance dies—Redis sessions survive instance loss.

Session vs JWT?

Sessions in Redis for server-rendered multi-instance; JWT for stateless APIs.

Redis down = all users logged out?

Yes—design HA Redis (Sentinel/Cluster)—Sentinel.

Serialize large objects in session?

Keep session small—store user id, load profile from DB.

GDPR logout everywhere?

Track session ids per user or use short JWT + refresh with revoke list.

Spring Boot 3 package names?

Use current spring-session-data-redis version matching Boot BOM.