3. Stateless REST, cookies, and “what if there’s no cookie?” — the thing that bugs you.
This is a genuinely good confusion, because two true statements look contradictory: “REST is stateless” and “there’s a session cookie.” Let me resolve it.
“Stateless” means: the server keeps no memory of you between requests. Each request must carry everything the server needs to handle it. The server doesn’t remember “oh, this is the guy from 3 requests ago” on its own.
So how does a session work then? The client carries the state’s key — the cookie holds a JSESSIONID, and sends it on every request. The server doesn’t remember you; you remind the server who you are, every single time. That’s actually still “stateless-ish” from the server’s view — it’s reacting to what the request carries, not to its own memory.
Now your three sub-questions:
-
What if there’s no cookie? Then there’s no session — the server treats you as brand new. First-ever request has no cookie; the server creates a session and sends
Set-Cookie: JSESSIONID=...back; the browser stores it and sends it on subsequent requests. No cookie = no continuity = truly stateless. (Pure REST APIs often work exactly this way — no session at all; instead each request carries a token, like a JWT in theAuthorizationheader, which is the “carry your identity every time” idea without a server-side session.) -
“How is it stateless if there’s a cookie?” Because the cookie lives on the client, not the server. The server holding no memory = stateless. The client re-presenting a cookie each time doesn’t break that — the state’s home is the browser, and for the server each request is self-contained.
-
Sticky load balancer / Redis session store — you’ve already spotted the exact problem this creates. If the session object lives in one server’s memory (classic Tomcat), and you have 5 servers behind a load balancer, then request 2 might hit a different server that doesn’t have your session. Two fixes, both of which you named:
- Sticky sessions — the load balancer pins you to the same server every time (by cookie/IP), so your in-memory session is always there. Simple, but fragile: that server dies, your session’s gone, and load balances unevenly.
- External session store (Redis) — pull the session out of any single server’s memory into a shared Redis. Now all servers read the same session; any server can handle any request. This is the modern answer, and it makes your app horizontally scalable and restart-safe. Spring Session does exactly this.
The senior framing: “In-memory sessions force sticky load balancing, which doesn’t scale or survive restarts. Externalizing to Redis makes the app truly stateless per-node, so any instance handles any request.” That’s a strong thing to say.
LB
C- Sticky load balancer / Redis session store — you’ve already spotted the exact problem this creates. If the session object lives in one server’s memory (classic Tomcat), and you have 5 servers behind a load balancer, then request 2 might hit a different server that doesn’t have your session. Two fixes, both of which you named:
- **Sticky sessions** — the load balancer pins you to the _same_ server every time (by cookie/IP), so your in-memory session is always there. Simple, but fragile: that server dies, your session's gone, and load balances unevenly.
- **External session store (Redis)** — pull the session _out_ of any single server's memory into a shared Redis. Now _all_ servers read the same session; any server can handle any request. This is the modern answer, and it makes your app **horizontally scalable** and restart-safe. Spring Session does exactly this.
The senior framing: _"In-memory sessions force sticky load balancing, which doesn't scale or survive restarts. Externalizing to Redis makes the app truly stateless per-node, so any instance handles any request."_ That's a strong thing to say.