The constraint in one sentence
The server must not depend on out-of-band server-side session memory to know what this request means. Each request carries whatever credentials, identifiers, and context the server needs to authorize, route, and execute the operation.
Statelessness is about application correctness, not “the server never stores anything.” Databases, caches, and queues hold resource state. The constraint forbids client session state that only exists in one server’s RAM and is required to interpret the next HTTP message.
What counts as REST-ish
Tokens and credentials in the message
Authorization: Bearer <token> — the token encodes or references identity; any app instance can validate it (JWT signature, introspection endpoint, shared session store keyed by token id).
Cookies carrying opaque session ids — REST-ish when every instance can resolve the cookie to identity via a shared store (Redis) or self-contained token, not when only server #3 remembers the shopping cart in local heap.
The state lives in the message (header/cookie) or in shared infrastructure, not in hidden affinity to one JVM.
Correlation and request context
X-Request-Id, trace headers, idempotency keys — all travel with the request. The server does not need to recall “we were on step 2 of checkout” from RAM; the client sends the draft order id or resume token.
What breaks statelessness
- Sticky sessions required for correctness — load balancer pins user to server A because only server A holds their session map.
- In-memory shopping cart on one node with no replication; next request hits another node and cart is empty.
- Server-side multi-step wizard where step 3 only works if step 2 hit the same process.
Fixes: persist workflow state in a database or cache keyed by client-visible id; put resume tokens in the client; use shared session storage if you must keep server-side session objects.
Why interviewers care
Horizontal scaling — stateless app tiers add instances behind a load balancer without session migration.
Failure recovery — any instance can serve any request; no “lost session” when a node dies.
Intermediaries — proxies and API gateways can route, rate-limit, and cache without knowing which backend node “owns” the user.
Visibility — each request is self-contained in logs and traces; debugging does not require reconstructing hidden server RAM.
Teams still use sticky sessions for performance (local cache of user profile) or legacy reasons. In an interview, distinguish optimization (sticky but not required for correctness) from correctness coupling (broken without sticky).
Stateless vs “no server storage”
| Server stores | REST-ish? |
|---|---|
| Orders, users, products in PostgreSQL | Yes — resource state, not session state |
| JWT validation keys | Yes — infrastructure |
| Idempotency key → response in Redis (TTL) | Yes — derived from request header, any node can read |
| Per-user wizard progress only in one node’s RAM | No — violates statelessness for that flow |
Authentication patterns
Stateless JWT — server verifies signature and claims; no server-side session table. Trade-off: revocation is harder until tokens expire or you maintain a blocklist.
Opaque session id + Redis — cookie carries id; any app server looks up session in Redis. Still REST-ish: state is addressable from any instance via shared store, not local RAM only.
SAML/OAuth redirects — browser flows use redirects and codes; the API calls remain stateless with access tokens.
Pick one story and explain retry behavior: a retried request with the same Bearer token must produce the same authorization outcome.
Interview framing
“What does stateless mean in REST?” — No server-side client session required to interpret a request; context travels in headers, body, or URI. Resource data in databases is fine.
“Are cookies non-RESTful?” — No. Cookies that carry session identifiers are fine if any server can validate them without hidden local state.
“How does this relate to scaling?” — Stateless app layers scale out easily; stateful session affinity complicates deploys and failover.
Next: Status Codes & Errors — how clients learn outcomes without parsing JSON error strings.