Why your context window is always full, and why the agent gets worse right after it compacts
The agent didn't get dumber after compacting. It lost the material it was reasoning over, and you paid for the summary that lost it. What a context window really holds, why re-reads are the one waste with a hard definition, and why the size where your sessions start degrading is a personal number.
You're an hour into a session. The agent compacts. Afterwards it's a little off. It asks about something you settled twenty minutes ago, re-opens a file it already read, suggests an approach you explicitly rejected.
So you reach for the obvious explanation: the model got worse, or it's overloaded, or you've been quietly downgraded.
None of that happened. The model didn't lose capability. It lost the material it was reasoning over, and you paid for the summary that lost it.
What a context window actually holds
Worth being precise about this, because the mental model most people carry is wrong in a way that makes the rest confusing.
A language model has no memory between turns. None. It doesn't "remember" your conversation and it isn't "keeping track" of your project. Every single turn, the entire conversation is re-sent: your instructions, every prompt, every response, every file the agent read, every tool result it got back. The model reads all of it fresh and produces the next reply.
That's the whole trick, and it has two consequences people don't connect.
The first is that context isn't storage, it's a per-turn payload. Nothing accumulates in the model. It accumulates in the message you resend every time.
The second is that there's a hard ceiling on that payload, and it's the reason compaction exists at all.
Compaction is a symptom
Context compaction is what happens when the conversation stops fitting: the agent compresses the history into a summary and continues from the summary instead of the transcript. Good engineering, and without it long sessions would simply stop.
But it runs after a problem rather than toward a goal, and it charges you twice.
The first charge is tokens. Summarizing the conversation means reading the conversation, so you pay to process what's being compacted and pay again to carry the summary forward on every subsequent turn. It also resets the prompt cache holding your context, which is a real cost of its own and one that gets charged against the same rate-limit window you'll run out of on Thursday.
The second charge is detail. Some of what a summary drops you'll never miss. Some of it you'll spend the next six turns re-establishing, which costs tokens, which fills the window, which brings the next compaction closer.
That loop is the part worth internalizing: compaction creates the conditions for more compaction. A session that has compacted twice is usually not doing twice the work. It's been paying to relearn its own history.
What filled the window
The causes are unglamorous, which is why they survive:
- Files that never left: everything read in the first ten minutes is still being carried in the last ten, relevant or not.
- Whole files for one function: a large module pulled in to reference a small piece of it.
- Standing configuration: your
CLAUDE.md, skills, plugins, and MCP definitions occupy window space from turn one, before the task is stated. - One session, several tasks: the finished thing dragged into the unrelated new thing.
- Re-reads: the agent opening a file it already has.
The first four are the same phenomenon wearing different hats. The window accumulates and nothing prunes it. They're also where advice is easiest to give and hardest to follow, because you can't see what you're carrying.
The fifth is different, and it earns the rest of this post.
Re-reads have a hard definition
Most claims about context waste are soft. "Your window is inefficient" can't be falsified without a definition of efficient, and any single percentage attached to it is a number somebody chose.
Re-reads aren't like that. A re-read is precise: the agent reads a path already resident in context, with no intervening write to it. Nothing was stale. Nothing changed. The content was already present and got injected a second time.
Three properties follow from that definition, and together they make it worth more than the softer signals around it.
It's derived from content rather than activity. It doesn't count how much you did, it counts a specific event, so working harder doesn't inflate it and working less doesn't improve it.
It can't be gamed. The only way to look better on re-reads is to re-read less. Compare that to anything volume-based, which improves when you do less work.
And it names names. A rate is a number; a list of which files got re-opened, and how many times each, is a to-do list. In practice it's two or three files, usually the config, the type definitions, and the one enormous module everything touches. Once you've seen the list the fix takes a minute.
The waste is also unambiguous, which is rarer than it sounds. Carrying a file you no longer need is arguably wasteful, since it might become relevant again. Reading a file you already have is paying twice for one thing, with no argument available.
Your knee is a personal number
The last piece is the one people most want to be universal.
Somewhere there's a context size past which your sessions start going wrong, where re-reads and tool errors stop being flat and start climbing. Below it you're fine. Above it you're fighting the agent and calling it a bad day.
That onset isn't a property of the model. It's a property of how you work: how many files a task tends to touch, how long you run before restarting, how much standing configuration you load, how specific your instructions are. Two people on the same model and the same codebase in the same week will have different ones.
So the number you want can't come from a blog post, this one included. Anyone publishing a universal threshold is either quoting a model's limit, which is a ceiling rather than a knee, or generalizing from one machine.
Your own history can produce it, though, because the shape is visible. Bucket your turns by how much context was loaded and look for where the trouble rate stops being flat. With enough sessions it's a curve with a bend in it. Without enough, the honest answer is that there isn't sufficient signal yet, which is also a real answer and better than a fabricated one.
Where to find all of this
The window leaves a paper trail. Every read, every path, every turn's token count is recorded in the session logs under ~/.claude/projects, which means a re-read isn't something you have to catch in the act. It's a query.
npx @promptster/cc-audit
Local, free, no account. The analysis is built from paths, tool calls, and token counts, so your file contents are never opened, and a plain run transmits nothing at all.
Four answers, in the order this post raised them: what share of your bill is carry rather than output, which files get re-opened while already resident and how often, what your always-on configuration costs per turn before the task starts, and where your own degradation curve bends. Or, honestly, that you don't have enough sessions yet for that last one to mean anything.
If you want the other half of the picture, where the week went rather than where the window went, that's why you hit your weekly limit on Thursday.
Frequently asked questions
Is compaction bad?
No. It's correct behaviour for a full window and the reason a long session can continue at all. But it's a recovery mechanism rather than a goal. Compacting often isn't a sign you're working hard, it's a sign the window was carrying more than the task required.Why does the agent seem worse right after it compacts?
Because it's reasoning over less. A summary is lossy by construction: the exact error text from twenty turns ago, the reason you rejected an approach, the shape of a file it read once. Capability didn't change, available material did. That's why the fix sits upstream rather than in how you prompt it afterwards.Does a bigger context window fix it?
It postpones it. A larger window means you compact later, but carrying things that stopped being relevant is just as wasteful in a big window as a small one. You simply go longer before anything forces you to notice.How often is too often?
There's no universal number, and anyone quoting one is guessing. The useful question is where your own sessions start to degrade, which is measurable from your history and varies a lot between people.Does running /compact manually help?
Compacting deliberately at a natural boundary beats being compacted mid-thought, because you control what gets summarized away. Starting a new session when the task changes is usually stronger still, since a new task rarely needs the old task's history and manual compaction still carries a summary of it forward.Can I see which files are being re-read?
Yes, and it's the most actionable thing in the picture. Re-reads are measurable from content rather than activity, so they can be named specifically: this file, this many times. That turns a vague sense of waste into a short list you can act on.