{"slug": "your-context-window-bills-you-every-turn", "title": "Your context window bills you every turn", "summary": "An engineer analyzed Claude Code's transcript files and found that context compaction resets the recurring token bill to zero, rather than being a tax. Across three sessions totaling 5,288 requests, the cache read-to-write ratio was 32:1, and caching alone reduced costs by 86% before compaction fired.", "body_md": "Claude Code compacted my session for the fourth time this week, and my first reaction was the normal one: annoyance. It just erased everything and I have to re-explain half of it.\n\nThen I pointed Claude Code at its own transcript files and did the arithmetic instead of the complaining. The transcripts are just JSONL on disk — every request, every token count, timestamped. Three sessions, 5,288 requests, a few minutes of parsing.\n\nThe reframe that came out of it: **compaction isn't the tax. It's the tax getting paid off.** The tax is every turn before that.\n\n**TL;DR**\n\nThere's no persistent working memory across a conversation. Each API call is stateless — the model sees whatever text is in the request, and nothing else. So a coding session's \"memory\" is an illusion built entirely out of re-sending: every prior file read, every tool result, every message, concatenated and shipped again, every single turn.\n\nPrompt caching is the thing that makes this survivable — [I've written before](https://ferhatatagun.com/blog/prompt-caching-nobody-measures) about the mechanics of that discount for teams billing the Messages API directly. This post isn't about that bill. It's about what the discount doesn't erase: a coding *agent's* context isn't a system prompt that sits still for five minutes: it grows every tool call, and it's the agent itself — not your app's request pattern — deciding how much gets re-sent on turn 500.\n\n\"A fraction of full price\" is not \"free.\" It's a discount on a bill that still arrives every turn. The number of tokens in context is not a one-time cost you paid when you pasted that file in — it's a recurring line item for every remaining turn in the session.\n\nI pulled this from three Claude Code project transcripts — `.jsonl`\n\nfiles sitting in `~/.claude/projects/`\n\n, one line per event, a `usage`\n\nobject on every assistant message.\n\n| Session | Requests | Cache read | Cache write | Output |\n|---|---|---|---|---|\n| A | 498 | 132M | 2.2M | 0.34M |\n| B | 2,138 | 670M | 24M | 1.5M |\n| C | 2,652 | 1,191M | 36M | 2.3M |\nTotal |\n5,288 |\n1,993M |\n62M |\n4.2M |\n\nThe read:write ratio — how many times a token gets billed for being *re-seen* versus the one time it's billed for being *newly added* — sits at **32:1** overall, and climbs inside any single long session as context grows.\n\nSession C is the sharper case. It hit four automatic compactions:\n\n| Trigger | Context size at compaction | Duration |\n|---|---|---|\n| auto | 968,704 tokens | — |\n| auto | 996,078 tokens | 108.7s |\n| auto | 999,313 tokens | 139.5s |\n| manual | 771,369 tokens | 140.5s |\n\nEvery one clusters right at the ~1M ceiling — the auto-compactor is doing exactly what it should, firing before the window overflows. And every one shows the same signature in the raw usage data: cache-read tokens at ~990K on the request immediately before, then **0** on the first request after. The entire accumulated context — everything that made every subsequent turn progressively more expensive — gets discarded and replaced with a summary. Turn 901 is cheap again.\n\nThat's the reframe. The compaction isn't losing your context. It's the moment the recurring bill resets to zero — at the cost of a two-minute pause and whatever the summary didn't preserve.\n\nAt published list-price API rates, running the actual token mix from these three sessions through the cached-price and never-cached-price formulas gives:\n\nThat's an 86% reduction from caching alone — before compaction ever fires.\n\nTwo caveats, because getting this wrong would be exactly the kind of unverified number [I've written about before](https://ferhatatagun.com/blog/the-eval-is-the-deliverable):\n\n*Isn't this just... how caching is supposed to work?* Yes. That's the point, and it's worth stating plainly instead of implying context bloat is a bug: caching is what makes long sessions economically viable at all, and it's doing its job well — 86% off is not a rounding error.\n\nBut \"there's a discount\" and \"there's no cost\" get quietly treated as the same thing when you're forty tool calls into a debugging session, and they aren't. A discounted recurring charge is still a recurring charge. The fact that it's 90% off doesn't change that it's billed again next turn, and the turn after, for as long as that token stays in the window.\n\nNothing exotic — the levers were already sitting in Claude Code's own design, this just explains why they matter more than they look like they do:\n\nNone of this is news framed as \"AI context windows are expensive.\" It's closer to a hosting-bill instinct engineers already have for anything metered per-request — it just hadn't been pointed at a coding agent's own conversation before, mostly because nobody's context window ships with a bill attached. This one does. It's just sitting in a JSONL file, one line per turn, waiting to be added up.", "url": "https://wpnews.pro/news/your-context-window-bills-you-every-turn", "canonical_source": "https://dev.to/ferhatatagun/your-context-window-bills-you-every-turn-1j6e", "published_at": "2026-09-03 06:40:27+00:00", "updated_at": "2026-09-03 06:52:39.851708+00:00", "lang": "en", "topics": ["large-language-models", "ai-infrastructure", "developer-tools"], "entities": ["Claude Code", "Anthropic"], "alternates": {"html": "https://wpnews.pro/news/your-context-window-bills-you-every-turn", "markdown": "https://wpnews.pro/news/your-context-window-bills-you-every-turn.md", "text": "https://wpnews.pro/news/your-context-window-bills-you-every-turn.txt", "jsonld": "https://wpnews.pro/news/your-context-window-bills-you-every-turn.jsonld"}}