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