Explainstuff.mebeta
All concepts
Basicsbeginner7 min

Statelessness

Why servers that remember nothing locally are the secret to scaling out cleanly.

Every useful web app has to remember things between requests. When you log in, the app remembers who you are on the next page. When you add an item to a cart, it's still there when you check out. When you upload a large file in chunks, the server holds onto the pieces until they're all in. That remembered data — sessions, carts, partial uploads, anything carried from one request to the next — is what engineers call state.

The interesting question isn't whether an app has state. It always does. The question is where that state lives — and that single choice quietly decides how easily your system can grow.

The problem: stateful servers

The tempting approach is to keep state right where it's convenient: in the server's own memory. The first time you log in, server A creates a session object and holds it in RAM. That's fast and simple — until you run more than one server.

Now there's a catch. Your next request might land on server B, which has never heard of you and has no session in memory. Suddenly you appear logged out. To paper over this, systems often use sticky sessions: once you've been handled by server A, the load balancer pins you to server A for the rest of your visit.

Stateful — sticky sessions
request
Client
Load Balancer
Server 1
Server 2 · session
Server 3
The session lives on Server 2, so this client must keep going back to Server 2.

Sticky sessions "work," but they make the whole fleet rigid. Because each user's state lives on one particular machine, the servers are no longer interchangeable. You can't freely add a new server (it starts empty and gets no existing users), you can't cleanly replace one for maintenance, and you can't balance load evenly because traffic is glued to wherever each user first landed.

Worst of all is failure. If server A crashes, it doesn't just go offline — it takes every session, cart, and half-finished upload it was holding down with it. Those users are abruptly logged out and lose their in-progress work.

Watch out

Local state is a trap that hides until you scale. On one server everything looks fine. The pain only shows up when you try to add a second server, replace a sick one, or survive a crash — exactly the moments you most need things to go smoothly.

The solution: statelessness

A stateless server keeps no per-request state in its own local memory. Each request arrives carrying (or pointing to) everything needed to handle it, the server does its work, and it forgets the request entirely once the response is sent. Nothing important is left behind on that particular machine.

The state didn't vanish — it moved to a shared store that every server can reach. Sessions and carts go into a shared database or cache like Redis; uploaded chunks go into shared object storage; sometimes the user's identity is even carried inside a signed token on each request, so the server doesn't have to look it up at all.

Stateless — shared store
request
Client
Load Balancer
Server 1
Server 2
Server 3
Shared store
Any server handles any request; the session lives in a shared store, not on a server.

Once state lives in a shared place, the servers become truly interchangeable. Any server can handle any request, because whatever it needs — your session, your cart, your upload — it fetches from the shared store rather than from its own memory. There's no reason to pin you to a particular machine anymore.

That's a profound shift. If a server crashes mid-request, you simply retry and a different server picks it up, your session intact in the shared store. Adding capacity is as easy as booting another identical, empty server.

Tip

Stateless does not mean "no state." It means no state on the individual server. The state is still there — it just lives in one shared, durable place instead of being scattered across machines that might disappear. "Stateless server, shared state" is the pattern to remember.

Why it matters

Statelessness is the quiet precondition for two of the most important ideas in system design. It's what makes horizontal scaling possible: when servers hold no local state, you can add or remove identical machines on demand without anyone losing their session. And it's what makes load balancing clean — the balancer is free to send each request to whichever server is least busy, instead of being forced to honor sticky sessions.

The takeaway is simple: keep your servers forgetful and put the memory somewhere shared. Stateless servers are cheap to add, safe to lose, and easy to balance — which is exactly what you want when your app starts to grow.

Key takeaways

  • "State" is the data a system remembers between requests — login sessions, shopping carts, partial uploads.
  • A stateful server keeps that data in its own local memory, which pins each user to one specific machine.
  • Sticky sessions make it hard to add, replace, or balance servers, and a crash wipes out that user's state.
  • A stateless server keeps no per-request data locally; anything that must persist goes to a shared store.
  • Statelessness doesn't mean "no state anywhere" — it means the state moved to a shared place so any server can serve any request.

Keep going