Stateless vs Stateful Architecture

📘 Chapter 3: Web Architecture Patterns ⏱️ 8 min read 🏗️ Lesson 011

Here's the question that determines whether you can scale horizontally: does your server need to remember anything between requests? If yes, you have a stateful server. If no, you have a stateless server. This distinction is one of the most consequential decisions in distributed system design.

What Is "State"?

State is any data the server remembers between requests from the same client. Shopping cart contents, login sessions, partially filled forms, in-memory caches tied to a specific user — all state.

Stateful vs Stateless — In One Sentence Each

  • Stateful: The server stores information about the client between requests. If you hit a different server, your context is lost.
  • Stateless: Every request contains everything needed to process it. Any server can handle any request from any client.

Stateful Architecture: Sticky Sessions

In a stateful setup, each user's session data lives in the memory of a specific server. The load balancer must route that user to the same server every time — called "sticky sessions" or "server affinity."

Stateful: User Bound to One Server 👤 Alice 👤 Bob 👤 Carol Load Balancer (sticky sessions) Server A Alice's session ✓ Server B Bob's session ✓ Server C Carol's session ✓ ⚠️ If Server A dies, Alice loses her session
Figure 1: Stateful — each user is locked to a specific server. If that server dies, the session is lost.

Stateless Architecture: Any Server, Any Request

Stateless: Any Server Handles Any Request 👤 👤 👤 Load Balancer (round robin) Server A Server B Server C Redis Shared Session Store ✓ Server A dies? No problem — B and C continue seamlessly
Figure 2: Stateless — any server can handle any request. Session state lives in an external store (Redis).

Why Stateless Wins at Scale

ConcernStatefulStateless
Adding serversComplex — must rebalance sessionsTrivial — just add and route
Removing serversUsers on that server lose stateNo impact — others pick up load
Auto-scalingHard — can't easily spin up/downNatural — scale on demand
Deploy/restartMust drain sessions firstRolling restart, zero downtime
Load balancingSticky (uneven distribution)Round-robin (even distribution)
Failure recoverySession data lostTransparent failover

Where Does State Go?

Stateless doesn't mean "no state." It means state is externalized — stored outside the application servers in shared, persistent stores.

Common External State Stores

StoreBest ForSpeed
RedisSessions, cache, real-time dataSub-millisecond
MemcachedSimple key-value cachingSub-millisecond
DatabaseDurable session storage1–5ms
JWT tokensAuth state in the request itselfZero (no lookup needed)

The Session Problem

HTTP is inherently stateless — each request is independent. But users expect continuity: "I logged in, I have items in my cart." Here's how stateless architectures solve this:

Pattern: Server-Side Sessions with External Store

// User logs in → create session in Redis
session_id = generate_uuid()
redis.set(session_id, {user_id: 42, cart: [...]}, expire=3600)

// Set cookie with session ID
Set-Cookie: session_id=abc123; HttpOnly; Secure

// Any server can now look up this session:
session = redis.get(request.cookies.session_id)

The session ID travels with the request (cookie or header). Any server can retrieve the session from Redis. No sticky routing needed.

Pattern: JWT (State in the Token)

// User logs in → server creates signed token
token = jwt.sign({user_id: 42, role: "admin"}, SECRET)

// Token sent with every request
Authorization: Bearer eyJhbGci...

// Any server can verify without external lookup
payload = jwt.verify(token, SECRET)

With JWT, the state travels inside the request itself. No external store needed for basic auth. Trade-off: you can't easily revoke a token before it expires.

Real-World Examples

Heroku & The Twelve-Factor App: Heroku's platform enforces statelessness by design. Their "12-Factor" methodology (Factor VI: Processes) states: "Twelve-factor processes are stateless and share-nothing." Your app can be killed and restarted at any time. Any file you write to the local filesystem disappears on the next deploy. This constraint is what makes Heroku's auto-scaling and instant rollbacks possible.

Why gaming servers are stateful: Multiplayer game servers often maintain in-memory game state — player positions, physics simulations, world state — updated 60 times per second. Externalizing this to Redis would add unacceptable latency. The trade-off: if a game server crashes, the match is lost. Gaming companies mitigate this with periodic state snapshots, but accept that some stateful architecture is unavoidable for real-time simulation.

Interactive: Stateful vs Stateless Failure Simulation

Simulate what happens when you add/remove servers in each architecture. Watch how users are affected.

Stateful Setup

Stateless Setup