explainedExplained5 min read

Why Stateless MCP Is Better for AI Agents

Stateless sounds like a word for engineers. It isn't. It's a simple idea about memory — about whether a server has to remember you. And that one thing decides whether you can grow your AI agents by just adding more machines.

Ask why an AI agent setup gets hard to grow and you'll usually hear about traffic — too many requests, coming in too fast.

That's almost never it. The real limit is far smaller, and much stranger. You can see the whole thing in one customer question.

One question, four tool calls#

An AI support agent gets asked something simple: where is my order?

Simple to ask. Not simple to answer. To reply, the agent has to look up the customer's account, pull up the order, check the shipping, and update the ticket. Four tool calls for one sentence.

Diagram: a customer asking 'where is my order?' feeds into an AI support agent labelled one question in, four tool requests out. The four calls are listed — look up the customer account, pull the order details, check the shipping status, update the support ticket. Below, a multiply band shows 1 customer equals 4 tool calls, 100 customers equals 400, and 1,000 customers equals 4,000 tool calls in the same few seconds, drawn as rows of small squares. A footer reads: the volume isn't the hard part; the hard part is whether the server has to remember you.
One question, four round trips. Multiply that by a thousand customers and you get the number everyone worries about — which is not the one that hurts.

Now a thousand people ask at once. That's four thousand tool calls in a few seconds.

That sounds like the scary part. It isn't. Websites have handled traffic like that for decades — you put more machines behind a traffic director, and it sends each request to whichever machine is free.

But that trick has one requirement.

Every machine has to be able to answer any request.

Break that, and adding machines stops helping.

The problem was memory#

Not memory as in RAM. Memory as in: this one server is holding something about you that the others don't have.

That's how MCP used to work. The agent said hello once, and the server handed back a session ID — a little ticket. After that, every request had to bring that ticket back to the same server, because only that server knew what it meant.

Diagram of the old stateful MCP shape. An agent sends initialize through a load balancer that wants to send the request anywhere but can't. Three servers are shown: Server A and Server C are greyed out and marked idle, doesn't know you, with red crosses on the routes to them; Server B is highlighted and holds your session in memory. A badge shows B minted Mcp-Session-Id 7f3a91c4, and a note reads that every later request must come back to B, and if B restarts, redeploys or scales down the session is gone. Below, three cards show the workarounds and their costs: sticky sessions, whose affinity breaks on every restart, deploy and scale-down; a shared Redis store, which adds a network hop on every tool call and one more thing that can go down; and gateway routing, which makes the load balancer speak MCP.
One small fact, held by one machine, needed on every later call. Everything after that is a workaround.

So the traffic director can't do its job anymore. It has three options, and all three are worse than they look:

Always send this agent back to Server B. Works right up until Server B restarts, or you update your app, or the system shuts a machine down to save money — all things you do on purpose, all the time.

Put the session somewhere all the servers can read it. Now every single tool call makes an extra trip to fetch it, and if that shared store goes down, so does everything.

Teach the traffic director to read MCP and send each request by hand. Now the traffic director has to understand your app to do its job.

Each one is a way of buying back the thing you already wanted: any server, any request.

What stateless actually means#

It's blunter than the word suggests. Every request brings everything it needs. Nothing is looked up. Nothing was supposed to be remembered.

Put the two side by side and the picture makes the argument on its own:

Two panels under the heading Stateless MCP. On the left, STATEFUL — the server has to remember you: a cyan agent box is joined to an amber server box by an amber line with a padlock on it labelled bound, and a dashed amber box reading 'your session' hangs beneath the server. A note reads: one ticket, held by one machine, so only that machine can answer you. On the right, STATELESS — every request stands on its own: a cyan agent box connects to a cyan REQUEST card listing tool and input, each with a green tick, which then arrows out to two amber server boxes — one solid, marked in green 'nothing retained', and one dashed, labelled 'any other one'. A note reads: the message carries what it needs, so any machine can answer it. Across the bottom: so the next request can go to a completely different server. A key notes cyan is the agent and its requests, amber is the servers and tools they reach.
Left: the agent and the server are locked together, and your session hangs off that one machine. Right: the request carries what it needs, and the server keeps nothing.

That padlock is the whole problem in one symbol. Take it off, and the next request can go to a completely different server — because there was never anything on the first one worth going back for.

Two reasons that actually pays off#

Reason 01 — scalability. Because no request depends on one server remembering anything, the work can spread across as many servers as you like. More agents, more requests? Add more servers. The system grows with demand instead of fighting it.

Reason 02 — flexibility. No request is tied to one specific machine, so whichever server is free can pick it up and finish the job. That matters most in exactly the place agents actually live — cloud setups where machines come and go all day long.

Diagram headed Reason 02, Flexibility — no request is tied to one specific machine. In the BEFORE row, four amber instance boxes sit side by side and a cyan arrow labelled 'request in flight' points down at instance 2. In the second row, headed 'then instance 2 goes away — a restart, a deploy, a quiet hour', the request that was headed there curves across to instance 3, which is outlined in green and marked with a green tick reading 'served anyway'. Instance 2 is now a dashed grey outline labelled 'gone'. A closing line reads: instances come and go constantly — and nothing breaks when one goes away.
A machine disappearing mid-job is normally an incident. Here it's a shrug — the request lands somewhere else and gets served anyway.

In July 2026, this became the rule#

Servers were always allowed to work this way. You just had to know to do it.

Then MCP made it the only way. In the version dated 28 July 2026 — two days before this video went up — sessions and session IDs were taken out of the rules completely. A modern server is now told to ignore an old session ID and never hand one out.

Comparison table titled July 2026, what MCP took out, with five plain-language rows. Saying hello first: the agent introduced itself once at the start, becomes no introduction, every message says who it is. The session ticket: the server handed one back and every later message had to bring it, becomes gone, servers aren't allowed to hand one out. A line held open: a second connection kept open on the side so the server could call back, becomes nothing held open, the server answers when it's asked. If the connection drops: pick up where you left off, becomes send it again, it's a fresh request. Remembering between calls: held quietly inside the session, becomes a receipt you're given and hand back yourself.
Five things that all assumed the server was still holding something for you. All five replaced by something that doesn't.

Everything built on top of the old idea went with it: the extra line held open on the side, the "pick up where we left off" feature, and the introduction at the start.

The state doesn't disappear — it moves#

This is the part most explanations skip, and it's the most useful bit.

Taking sessions away doesn't remove the things your work genuinely has to remember. A half-finished upload is real. A long list you're partway through is real. What changed is that the protocol won't quietly hold it for you anymore — so it has to sit somewhere you picked.

Diagram titled: stateless doesn't delete state, it moves it somewhere you can see. Five rows. The details themselves — most of what a session held was just something nobody wanted to send twice, so send it. A receipt, highlighted — the server names the thing, an upload, a list, a half-built draft, and gives you an id you hand back next time. Your database — the ticket, the order, the customer record, never the transport's job. The login — who's asking was already proven on every request, the tool layer just stopped keeping a second copy. The client's own notes — the server says how long its answer stays fresh, so the client keeps the tool list itself. Footer: the state doesn't vanish, it stops being invisible.
Five places it can land. All five are things you already owned — which is rather the point.

The official answer is deliberately boring. If a server really does need to remember something between calls, it gives you a receipt — an id for the upload, the list, the draft — and you hand that back with your next request, like any other detail.

The difference between a receipt and a session isn't cleverness. It's that you can see a receipt. You can save it, expire it, hand it to a different server, and know exactly what happens if you lose it. A session was a promise you couldn't look at.

And most of what sessions held was never really memory anyway. It was a detail nobody wanted to send twice.

What you give up#

Two honest costs, because a post that only lists wins isn't worth reading.

If the connection drops mid-call, there's no picking up where you left off. You send the whole thing again. That's simpler to think about — but it's now your job, not the protocol's.

Every request is slightly bigger, because it repeats a few details each time. Against a tool call that's about to go and hit a database, that's nothing. But it is the price of everything above.

Why this suits agents so well#

Here's the part that makes it click.

The agent was already working this way.

Every time an AI model takes a turn, it's sent the whole conversation again — the instructions, the question, every result so far. The model doesn't remember you between turns. That's not a flaw. It's the reason you can put a model behind as many machines as you like.

Diagram: the agent was already stateless, the tool layer was the odd one out. The top band shows three turns, each a longer bar than the last — turn 1 is the system prompt plus the question, turn 2 is all of that again plus the first tool result, turn 3 again plus the second — with the note that the model server keeps nothing between turns and every turn is a fresh, complete request. The middle line reads: so the odd one out was never the model, it was the tool layer, the only part of the loop that asked to be remembered. The bottom band shows one agent with one task and three tools, no connection held, whose three calls are answered by Server A, Server C and Server B respectively, with the note that not one of them had to be told anything first.
The model half of the loop never held on to anything. Now the tool half doesn't either.

So the agent was already re-sending everything to one service on every step — and then, in that same step, asking a second service to please remember last time they spoke.

The tool layer was the only part of the loop with a memory. Which made it the only part you couldn't grow by adding machines.

The verdict#

Comparison grid: same tool call, two ways of doing it, across six situations. A request arrives — stateful has to reach the one server that knows you; stateless says any server will do, send it wherever. A server dies — the conversation dies with it, versus the next request goes elsewhere and works. Traffic doubles, highlighted — add servers plus pinning plus a shared store to read, versus add servers, that's the whole sentence. You update the app — wait for everyone to finish or cut them off mid-call, versus just restart them, nothing to wind down first. A call fails midway — pick up where you left off and hope the server kept up, versus send it again, nothing was left behind to tidy up. Nobody is calling — servers stay up holding sessions open, versus shut them all off, pay per call not per connection. Footer: stateless doesn't make one tool call faster, it makes the thousandth one cost the same as the first.
Same tool call. The difference shows up on all the days you'd rather not think about.

So — why is stateless MCP better for AI agents?

  • Every request is self-contained. Which means it can be answered by anything, and that's what turns "add more servers" into a complete plan.
  • Nothing to remember, nothing to reconnect to. A machine dying, an update going out, a call timing out — none of it is special anymore.
  • You scale by adding servers, not complexity. The architecture doesn't change as you grow. You just add more of it.
  • And what you really do need to remember becomes visible — a receipt you can look at, instead of a session you never could.

The scary number was never the four thousand requests. It was one small fact, sitting in one machine's memory, quietly deciding that only that machine was allowed to answer.

Take that away, and the rest is just normal web traffic.

sources
  1. 01MCP specification 2026-07-28 — sessions removed from the Streamable HTTP transport
  2. 02MCP specification 2026-07-28 — the list of what changed
  3. 03Model Context Protocol blog — the 2026-07-28 release
  4. 04Solo.io — what the stateless change means in practice

Watch the full video

@thekernelcast on YouTube

▶ watch on YouTube
comments
// comments load here once Giscus is configured