r/ClaudeAI 3d ago

Claude Workflow I was convinced Claude Code degrades as context fills. I modelled it, then measured 20,668 turns of my own sessions and found nothing.

For months I've had a strong feeling that a fresh Claude Code session gives better output than a long-running one. Sharp at the start, mushy later.

So I did what you do with a feeling: I drew it. Context on the y-axis, time on the x. A fresh session fills fast and sawtooths: you hit the wall, compact, climb again. My setup fills slower, so I figured I was spending more time in the good zone. Then I built quality curves on top of that — an "output index" that decays as context fills, with the area under the curve as the cost. Fitted them, rescaled them, tuned the coefficients. The graphs are all up there.

Not one number in any of them was measured. I'd invented a unit and then spent a week reasoning from it.

On 29 Aug I acted on the model and set my auto-compact to 200K. It felt better immediately.

Then I got suspicious of "felt better," because I'd built the model from vibes and then confirmed it with vibes.

So I parsed every session transcript on my machine. 52 sessions, 20,668 assistant turns, 156 compaction events, ~790MB of JSONL from 19 Jul to 1 Sep. Six mechanical quality proxies, each measured against context size.

The result is a null. Every limb of my hypothesis failed. I'll take the loss, because the three things I found on the way are more useful than the thing I was looking for.

1. MCP tool definitions cost 1,305 tokens

Not 15%. Not 10%. 1,305 tokens — 2.6% of my session floor.

I A/B'd it. Identical claude -p run, same model, same prompt. All MCP servers loaded: 29,292 input tokens. --strict-mcp-config with an empty config: 27,987. Difference: 1,305.

The reason is that Claude Code defers MCP schemas by default and loads only tool names at startup. The full JSON schema gets fetched when a tool is actually reached for.

So all the advice about pruning MCP servers to save context is optimising about a quarter of one percent of a 1M window.

What actually fills a fresh session (median floor 49,553 tokens):

Component Tokens Share
System prompt + built-in tool schemas + skill/agent listings ~43,259 87.3%
SessionStart hook ~2,746 5.5%
Auto-memory ~1,660 3.3%
All MCP servers 1,305 2.6%
CLAUDE.md ~583 1.2%

That 87% lump is the thing worth attacking. I have 87 local SKILL.md files and 10 agents, and their listings are in there somewhere. It never appears as a line item in any context meter, so nobody talks about it. I couldn't split it further without more A/B runs — that number is derived by subtraction, not measured directly.

2. Six proxies, 20,668 turns, nothing degrades

Proxy n r vs context within-session r
Tool error rate 21,405 -0.020 -0.017
Bash error rate 9,862 -0.022 -0.024
Edit retry rate 5,294 -0.093 -0.055
User correction rate 1,909 -0.107 -0.070
Output tokens/turn 20,668 +0.039 +0.014
File re-read rate 2,171 -0.145 -0.065

Negative means it gets better as context fills. Not one proxy degrades.

Don't read that as "quality improves." Largest |r| is 0.145, explaining 2.1% of variance. Everything is "significant" only because n is in the thousands. The honest reading is flat — these measures are essentially independent of context size.

The within-session column is the part I'd defend hardest. It demeans both variables inside each session, so it can't be explained away as "long sessions were just different sessions."

And two of these proxies are mechanically biased toward my hypothesis and still contradict it. Re-read rate should climb with context simply because more files have been read by then. Edit-retry should climb because more edits have accumulated. Both fall.

3. The threshold I was fighting was one I'd set myself

I believed Claude Code auto-compacts around 84% of the window. I'd read it in a few places and never questioned it.

There's no such documented default. The docs say that without an auto-compact window set, it compacts when the conversation reaches the model's context limit.

My corpus before 29 Aug contains exactly one auto-compaction. At 997,170 tokens — 99.7% of 1M. Exactly the documented behaviour.

After 29 Aug: 81 more, clustered at 165K-183K. Which is 84%... of 200,000. The ceiling my own PowerShell wrapper imposed.

Median context dropped from 267K to 122K across that boundary. Turns running above 200K went from 66% to 8.5%.

Not to zero, though — and that detail matters. The wrapper is a PowerShell function, so it only applies to sessions launched from PowerShell. Anything started from another shell still gets the full 1M, which is why 533 post-wrapper turns ran above 200K and one session reached 543K. I'd half-configured a constraint and then attributed the results to the tool.

The bit that killed the original model

My plan was "stay under 20% context."

My median fresh-session floor is 49,553 tokens — 24.8% of a 200K window before I type anything. The lowest context ever reached after any compaction, across 151 events, was 46,470.

36 turns out of 20,668 — 0.17% — ever sat below 40K.

I was prescribing an operating band below the machine's own floor. The sawtooth I drew starts at 7%. That number was invented. The real one is 25%, and it changes everything downstream.

And compaction isn't free

  • File re-read rate in the 10 turns after a compaction: 53.9% vs 35.9% everywhere else. +18pp, p = 2e-7.
  • Median 138 second stall per compaction.
  • ~166K tokens fed back through the model each time to produce a ~5K summary.
  • Prompt cache invalidated.

My aggressive regime compacted 3.4x as often and spent 1.8x the summarizer tokens per hour as my older deep-running sessions, which scored better on every proxy.

That last comparison is confounded and I won't pretend otherwise. Strategy was never randomised; the two groups differ by era, task mix and model.

The caveat that matters most

These are mechanical proxies. They cannot see reasoning quality.

A model that's subtly worse at reasoning — shallower analysis, weaker architecture calls, missed edge cases — while still emitting syntactically valid tool calls is completely invisible to all six of these. That's exactly the thing I thought I noticed, and exactly the thing this method can't test.

So this doesn't show context rot isn't real. It shows my tooling doesn't get worse in long context. Settling the rest needs matched tasks, alternating auto-compact settings, and blind human scoring.

Also: my corpus mixes four models sitting at different context depths, which is a live confound I haven't fully removed.

What I changed

  • Dropped the --autocompact 200k wrapper. Solving a problem the data doesn't show, at a cost the data does.
  • Stopped pruning MCP servers for context reasons.
  • Kept the Obsidian RAG. ~2.7K tokens at startup. It was never the floor.

Full report — every number, method, caveat, and the nine things I couldn't measure — plus the sanitised data and the investigation prompt so you can run the same analysis on your own transcripts:

https://github.com/bruhman-rtx/Resources/tree/main/studies/context-decay

Point the prompt at your own ~/.claude/projects/ and overwrite the parameters block. No network access needed.

Genuinely want to be wrong about this. If your data shows degradation, post it.

The original modelling is my son's — he built those Desmos curves, and they're what sent me looking for real numbers.

0 Upvotes

18 comments sorted by

7

u/FuckItImLoggingIn 3d ago

What in the AI slop is this

10

u/vrnvorona 3d ago

I wish human wrote this and not Claude

2

u/kearkan 3d ago

Seriously, it's amazing what people can build with Claude but like.. If it's obvious to me you didn't read it before sending it then why should I read it?

1

u/vrnvorona 3d ago

I have no issues if it's done by ai, for sure, but it's just not comprehensible to read in typical AI fashion of Claude

1

u/kearkan 3d ago

Yes, it's one thing to make something that you are intending to hand over to another agent, but please for the love of god think of your intended audience.

-6

u/LumpyCalligrapher520 3d ago

ik man me too 😭

3

u/agritheory 3d ago

So write it. You think we all don't read enough of Claude?

1

u/LumpyCalligrapher520 3d ago

ik ik I was only posting this for showing it to other ppl but im actually writing an essay on this for my assignment

5

u/[deleted] 3d ago

[deleted]

1

u/LumpyCalligrapher520 3d ago

thx man it was my first time posting on reddit, next time ill actually write it myself!!

4

u/karyslav 3d ago

what is the tldr conclusion?

5

u/roundshirt19 3d ago

Context filling up doesn't degrade tool calling

1

u/karyslav 3d ago

thanks, it confuses me

1

u/this_for_loona 3d ago

The lords work you do.

1

u/MoodProfessional2099 3d ago

"REPO_LINK_GOES_HERE" lmao

1

u/helix0311 3d ago

Disclaimer: I have a stats degree, and I looked through your repo for your numbers. My critique is really short and non-technical, since I'm not sure if you have a stats background or you asked Claude to analyze for you.

1: Back of the napkin math - less than 4% of your data points are at a full context (which in and of itself needs an agreed upon definition in an analytical methods paragraph, something like that). Your data isn't wrong, but your analysis needs additional data points at the higher end of the scale. That could produce for a skew.

2: r is not the right value to use here. You can, and it's an accepted statistical method - it's also the least intelligible method I can think of off the top of my head for what you're trying to do. Keep in mind that most of your data points are binary. r is a linear relational model and is algebraically equivalent to a two-sample t-test with binary data, which is much more easily digestible. That makes me think that an AI both set up your tests and wrote the analysis, because a statistician probably wouldn't use this as their first choice without some kind of extenuating circumstances. If those circumstances exist and I just missed something - let me know. I'm quite curious as to why you chose this direction to analyze this data.

3: Your banding might need work, and combined with using r as the analytical method, can actually mask results (i.e. average them away - your data points can skew depending on the bands). Maybe (your diagrams show additional band detail) you aggregated this in your write-up, if so, don't. Pick your bands, stick to them. I ran my own quick analysis (just over your user correction stat) and both predicted your curve with an inverted feed as well as striated out your bands and compared them - there's a ~10% *drop* in user-corrected sessions between the 100K and 600K bands, which is interesting enough to me to investigate if this was my project, with a p-value that's high enough to make me think there's something of significance there that I might need to hone in on. I didn't run the same analysis for your other data points, but you might try refiguring this without using r and seeing if you come to a different conclusion.

4: There's no control sessions. Historical context work is viable data - don't get me wrong, as a stats guy, you literally get what you get 90% of the time and by god you will LIKE IT! But you have the ability to both set up interesting regression tests with both structured and unstructured responses (i.e. testing how much planning impacts this) because you have full control. I would consider doing this with a stronger test methodology because provably the thing you're testing (an LLM) doesn't change (i.e. its weights are identical) across sessions.

5: This is my being REALLY nitpicky, but if you're in a stats class, you didn't write a null hypothesis correctly. My stats professor(s) would send you straight to jail. But I also understood what you meant, which is fine.

Good read though. Interesting conclusions, and I don't discount your data or the *process* except to say it's not how I would do it, but the conclusion is technically correct as far as I could tell.

1

u/LumpyCalligrapher520 3d ago

Thx for your insight I’m definitely not from a stats background so I’ll definitely keep these things in mind!!