Basicsbeginner10 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.

Step through one shopper's visit below. Ana signs in, fills her cart, and then her server restarts for an ordinary deploy. Predict what she sees on her next click before you look.

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 — and, as the scene shows, a routine restart counts. If server A crashes or is redeployed, 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, even though the other servers are perfectly healthy.

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.

Replay Ana's visit below with stateless servers. Predict what the same restart does this time, then flip the switch from Shared store to Signed token to see the other way to do it. Each one ends on its catch.

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.

Check yourself

After a deploy, users who were on one particular server complain they were signed out and lost their carts. Users on the other servers are fine. What's the most likely cause?

The catch: state still lives somewhere

Moving state off the servers doesn't make it disappear; it moves the risk too. Each approach has a price.

  • A shared store becomes something every request depends on. If the session cache goes down, every server fails at the same moment, which is worse than one server losing its users. Run it replicated, monitor it like your main database, and size it for the whole fleet. It also adds a network round trip to each request, which is usually small next to the work the request does.
  • A signed token needs no lookup, but the servers keep no list of tokens, so they can't cancel one early. If a token is copied, it keeps working until it expires. Keep lifetimes short (minutes, refreshed as the user stays active), keep tokens small since they ride along on every request, and remember that signed means tamper-proof, not secret: anyone holding the token can read what's inside unless it's also encrypted.

Many systems mix the two: a short-lived token for identity, and a shared store for bigger, changing data like carts.

Watch out

A shared store is a single point of failure in disguise. Teams often move sessions into one cache instance and call the servers stateless — then that one instance restarts and signs out every user at once. Stateless servers only buy resilience if the place the state moved to is at least as resilient as the fleet it serves.

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.

Check yourself

Your app keeps sessions in signed tokens that last 7 days. A user reports a stolen laptop and asks you to end every session they have, right now. What's the problem?

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.
  • The shared place becomes a dependency: a session store must be as resilient as the fleet, and signed tokens can't be cancelled before they expire.

Keep going