skip to content

What is Spring Session, and why would you externalize HttpSession to Redis or JDBC instead of using the servlet container's default session?

level: juniorimportance: must knowfreq 62%

answer

  1. Container keeps session in one JVM's heap
  2. SessionRepository-backed swap, code unchanged
  3. @EnableRedisHttpSession / @EnableJdbcHttpSession
  4. Scale without sticky sessions, survive restarts
  5. SESSION cookie replaces JSESSIONID

basics

~10 s

Spring Session stores the HttpSession in an external store (Redis, a database, etc.) instead of in the app server's memory. This lets multiple server instances share sessions and lets sessions survive restarts.

solid answer

~40 s

By default the servlet container (Tomcat/Jetty) keeps each HttpSession in the JVM's memory, so a session lives only on the one node that created it. Spring Session transparently swaps that implementation for one backed by an external store — Redis, a JDBC database, or Hazelcast. You add a starter and an annotation like @EnableRedisHttpSession; existing request.getSession() code is unchanged. The wins: horizontal scaling without sticky sessions (any node can serve any request), sessions survive app restarts and rolling deploys, sessions can be shared across multiple applications, and you avoid replicating session state between nodes. The trade-off is a network hop and serialization cost per session access, plus an extra piece of infrastructure to operate.

code

java · 20 lines
java
// Add dependency spring-session-data-redis, then:
@Configuration
@EnableRedisHttpSession // enables Spring Session backed by Redis
public class SessionConfig {

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(
            new RedisStandaloneConfiguration("redis-host", 6379));
    }
}

// Controller code is completely unchanged:
@RestController
class CartController {
    @PostMapping("/cart/add")
    void add(HttpSession session, @RequestParam String item) {
        session.setAttribute("lastItem", item); // now written to Redis
    }
}

go deeper

for a junior

Know the one-line purpose: put the HttpSession in an external store so multiple servers can share it and it survives restarts.

for a middle

Explain the sticky-session problem it removes and name the enabling annotations/repositories for Redis and JDBC.

for a senior

Discuss serialization requirements, the SESSION cookie change, and the availability trade-off (store becomes a login dependency).

for a principal

Frame it as part of an HA/zero-downtime deployment strategy vs. alternatives (sticky sessions, container replication, stateless JWT) and weigh operational cost.

## The problem it solves An **HttpSession** is the servlet API's per-user server-side storage — a map keyed by a session id that the browser echoes back in the **JSESSIONID** cookie. By default the servlet **container** (Tomcat, Jetty, Undertow) stores this map in the JVM heap of the node that created it. That creates several problems in a multi-instance deployment: - **No horizontal scaling without stickiness.** If node A created the session, only node A has it. You must configure the load balancer for *sticky sessions* (session affinity) so the user keeps hitting node A, which unbalances load and breaks when a node dies. - **Sessions die on restart/deploy.** Any redeploy or crash of node A wipes every session it held; users are logged out. - **No sharing across apps.** Two separate applications can't see each other's sessions. ## What Spring Session does **Spring Session** replaces the container's HttpSession implementation with one backed by a pluggable **SessionRepository**. It does this transparently: your controller code still calls `request.getSession()` / `session.setAttribute(...)`, but under the hood the session is read from and written to an external store. The store options each have an enabling annotation and repository: - Redis — `@EnableRedisHttpSession` (repository `RedisIndexedSessionRepository`) - Relational DB — `@EnableJdbcHttpSession` (repository `JdbcIndexedSessionRepository`, tables `SPRING_SESSION` + `SPRING_SESSION_ATTRIBUTES`) - Hazelcast — `@EnableHazelcastHttpSession` With Spring Boot you often just add the starter (e.g. `spring-session-data-redis`) and Boot auto-configures it; the annotation is the manual equivalent. ## What you gain - **Stateless-node scaling:** any instance can serve any request because session state lives outside the JVM. No sticky sessions required. - **Resilience:** sessions survive restarts, crashes, and rolling deployments. - **Cross-application sharing:** multiple apps pointing at the same store share sessions. - **Container independence:** session behavior no longer depends on the servlet container. ## Costs and gotchas - Every session read/write becomes a **network + serialization** round trip; attributes must be **serializable** (default is JDK serialization). - You now operate an **extra dependency** (Redis/DB) whose availability gates logins. - The session cookie changes: Spring Session issues a **SESSION** cookie (base64 value) instead of JSESSIONID by default. ## When to use it Use it whenever you run more than one instance behind a load balancer, do zero-downtime deploys, or want sessions to outlive a process. For a single always-on node with no HA requirement, the container session is simpler.

  • Does adopting Spring Session require rewriting code that uses HttpSession?
    No. That is the point of the design — Spring Session wraps the request so request.getSession() and setAttribute/getAttribute keep working. You add a dependency and an @Enable...HttpSession annotation; existing session code is untouched.
  • What constraint does externalizing sessions place on the objects you store as attributes?
    They must be serializable, because they are marshalled to the external store. With the default JDK serialization the classes must implement java.io.Serializable; you can switch to a JSON serializer (e.g. Jackson) to avoid Java-serialization coupling and make stored data readable.

saying these in an interview costs you the question

  • Thinking Spring Session requires rewriting all HttpSession calls
  • Believing it eliminates the session cookie entirely (it still uses a SESSION cookie / id)
  • Claiming it removes the need for any external infrastructure
  • Confusing it with a client-side / JWT stateless approach — the session is still server-side, just externalized

context