Skip to content

Insights

Stateless APIs: more than an architectural detail

· 7 Minuten Lesezeit

“Stateless” sounds like a word for architecture slides. Behind it sits a very practical question. What happens when the same application runs twice at once?

The problem starts with the second instance

As long as a backend runs exactly once, it can remember all sorts of things. Who is signed in. What is in the basket. Which step of a multi-page form somebody is on. All of that can go into the memory of the process, and it works perfectly well.

Until a second instance appears. A load balancer spreads the requests, and the second server knows nothing about what the first one remembered. Users get signed out at apparently random moments, half-filled forms vanish, and nobody can reproduce the fault reliably.

The same effect comes from a simple restart, by the way. If you get phone calls after every deployment because people have been thrown out of their session, you already have the problem without ever having scaled anything.

What stateless means in practice

Between two calls the server process keeps nothing. Everything meant to outlast a single call sits somewhere every instance can reach.

  • Signing in through a token the client sends along, or through a session held in the database or a cache rather than in the file system of one server.
  • Work in progress in the database, not in memory.
  • Uploaded files in a shared store, not on the local disk of one instance.
  • Background work in a queue that every instance can serve.

Laravel brings an intended route for each of these. The work is hardly ever about building something. It is about leaving the convenient shortcuts alone.

What it costs

Honestly, a little more discipline and a little more infrastructure. A shared cache has to be run, and so does a shared file store. And every place where somebody does put something locally after all becomes a time bomb that only goes off under load.

In exchange, growth stops being a rebuild. More load means more instances. If one fails, the next takes over. A deployment throws nobody out of their session. The failure of a single machine is then no longer an event but a line in a log.

And when it does have to be quick

Not every request can be answered in a few milliseconds. A PDF export, a call to somebody else’s system, sending mail to a thousand recipients. That sort of thing belongs in a queue. The call files a job and answers straight away; a background process works it off later.

The pleasant side effect shows up when the other system is having a bad day. Then it is not the user’s request that hangs, only the job. And the job can try again in ten minutes.

More on how we cut interfaces is under API and backend development.

Architecture diagram in three columns: on the left the entry points web interface, mobile app and partner system, in the middle a load balancer in front of three identical Laravel instances, on the right the shared database, a cache and a file store.
The same picture as on the service page, here as evidence: the state sits outside the instances. That is exactly what makes them interchangeable — and therefore multipliable.

FAQ

Briefly asked

Does stateless mean the application stores nothing?
No. Things are still stored, only in the database or a shared cache rather than in the memory of one particular server process. The question is where the state sits, not whether there is any.
Do we need this on small applications too?
The benefit shows up with a single instance already: a restart after a deployment throws nobody out of their session. And if growth comes later, the rebuild is already behind you instead of happening under pressure.

Keep reading

Other articles

A backend that has to grow?

Tell us which clients are meant to reach it. The shape of the interface follows from that.