Model performance degrades as a context window fills, well within the stated limit, because relevant information gets buried under accumulated history. The symptoms of a session going stale: repeated work, forgotten constraints, a plan the agent has lost track of. And the fix, which is compaction and a written plan, not a bigger window.
what context rot is
Context rot is the gap between what a model's context window can hold and what it can actually make good use of. The window is not full in the "out of room" sense; you are nowhere near the token limit. But the model's performance on the task in front of it gets measurably worse than it was an hour ago, in the same session, on work of the same difficulty.
This is not the same failure as running out of context. Running out of context is a hard stop: the next turn does not fit and something has to be dropped or the call fails. Context rot is softer and more common. It is the agent that used to name the right file on the first try now guessing, the agent that respected a constraint an hour ago now quietly ignoring it, while the transcript keeps scrolling and nothing errors out.
why it happens
A transcript is append-only. Every tool call, every file the agent read, every dead end it walked down and backed out of, every version of a plan it revised, stays in the context forever unless something removes it. None of that is free. On every turn the model has to weigh the whole history to decide what matters for the next token, and as the history grows the signal you actually want is a shrinking fraction of it.
Three mechanisms do most of the damage:
- Dilution. The constraint you stated at message four is one line in a window that is now four hundred lines long. It has not been deleted, but it competes for attention with everything the agent has done since, and attention is not distributed evenly across a long input.
- Staleness that looks current. Early in the session the agent decided the API returns a list. Later it discovered that was wrong and fixed the assumption for the current task. Nothing marks the earlier, wrong statement as retracted, so it still sits in the window as something the model wrote and therefore something it tends to trust.
- Self-reinforcement. A model conditions on its own prior output. A wrong turn early in a session is not neutral filler; it is precedent the model is now somewhat more likely to repeat or build on, because it is the most recent example of "how this kind of question gets answered" in its own context.
None of this requires the model to have gotten worse. It is the same model doing more work per useful fact, in a window that keeps adding facts and never subtracts them.
how it shows up in a coding session
Context rot rarely announces itself. It looks like the agent, not like an error message. The recognisable pattern:
That last row is the most diagnostic one. A model that is simply not capable of a task fails the hard parts and the easy parts alike. A model suffering context rot fails easy things it clearly could do, because the answer is no longer the most findable thing in its own window. If accuracy on trivial steps drops as a session gets longer, that is rot, not a capability ceiling.
why a bigger context window does not fix it
It is tempting to treat this as a limit problem: use a model with a larger window, or wait for the next one, and the issue goes away. That mistakes the mechanism. A larger window changes the point at which you hit the token ceiling. It does not change the fact that relevance dilutes as irrelevant history accumulates, because dilution is a function of the ratio of signal to noise in the window, not of how much headroom is left before the limit.
A useful, deliberately illustrative way to see the shape of it: if a fixed set of facts you actually need occupies roughly two thousand tokens, then at ten thousand total tokens they are a fifth of the window; at two hundred thousand tokens, the same facts are one percent of it. The facts did not get smaller or less true. Their share of what the model has to sift through to find them did. Doubling the window's capacity does not change that ratio; it just lets the ratio get worse for longer before you notice.
what actually helps
The fixes fall into two categories: reduce what is in the window, or stop adding to a window that has already accumulated too much.
Compaction and summarization
Periodically replacing a long stretch of transcript with a shorter summary of what happened and what is still true recovers some of the lost ratio. It genuinely helps, and most agent tools now do some version of it automatically when a session approaches its limit. Its weakness is that summarization is itself a judgment call made by a model reading a rotted context, so it can compress away the one caveat that mattered while faithfully preserving things that no longer do. Treat it as a pressure release, not a cure.
Ending the session on purpose
The more reliable move is simpler and less clever: stop the session before it rots, rather than trying to clean up after it has. A fresh session has an empty window and none of the accumulated dead ends of the old one. The cost is that a fresh session also has none of the decisions the old one made, unless you carry those forward deliberately.
the written plan file
The way to carry decisions forward without carrying the rot forward is to write down the decisions, not the transcript. A short file that states the current plan, the constraints that must hold, and what has already been done, gives a fresh session everything the old one earned without any of what the old one wasted.
# plan.md
## goal
Migrate auth middleware from session cookies to signed JWTs.
## constraints (do not violate)
- auth/middleware.ts is generated from schema/auth.yaml. Edit the
schema, not the generated file.
- Existing sessions must keep working during rollout; no hard cutover.
## done
- Added JWT signing helper in lib/jwt.ts (tested).
- Verified schema/auth.yaml supports a "bearer" claim shape.
## next
- Wire middleware to accept either cookie or bearer token.
- Update the three call sites in api/ that assume req.session.This file is small on purpose. It is not a transcript with the noise filtered out; it is a different kind of artifact, closer to what a human hands off at the end of a shift than to a chat log. Its entire value is that reading it costs a fixed, small amount of context no matter how many hours of work produced it, where the transcript it replaces would cost more the longer the work went on.
A workable rhythm for a session that runs long: work normally, and when you notice any of the symptoms above, or on a fixed checkpoint like finishing a subtask, update the plan file with what changed and what is still open, then start a new session pointed at that file instead of resuming the old thread. The old transcript is not wasted. It did its job by producing the plan. It just does not need to keep sitting in context after that.
common questions
What is context rot in AI coding agents?
Context rot is the degradation in a model's effective performance as its context window fills up, even well within the stated token limit. The window has room, but relevant information gets buried in accumulated history and the model does a worse job finding and using it.
Why does a long AI agent session get worse over time?
Every new turn adds tokens without removing any, so the fraction of the window that is still relevant to the current step keeps shrinking. The model also has to reconcile new instructions against its own earlier turns, some of which are now stale, wrong, or superseded, and nothing marks them as such.
Does a bigger context window fix context rot?
No. A bigger window changes when the effect becomes visible, not whether it happens. Degradation from clutter shows up well before the token limit is reached, so raising the limit mostly buys a longer runway before the same symptoms appear.
What are the practical fixes for context rot?
Compaction and summarization at meaningful checkpoints, and more reliably, ending the session before it rots and resuming from a short written plan file rather than the full transcript. The plan file carries only what still matters; the transcript carries everything that ever happened.
Skribbl shows you when a running session has been going long enough to be worth a look, alongside live spend, so a session that has quietly started repeating itself does not just sit there burning tokens unnoticed. Try it, or read how it tracks running sessions.