# Your context window bills you every turn

> Source: <https://dev.to/ferhatatagun/your-context-window-bills-you-every-turn-1j6e>
> Published: 2026-09-03 06:40:27+00:00

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.

Then 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.

The 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.

**TL;DR**

There'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.

Prompt 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.

"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.

I pulled this from three Claude Code project transcripts — `.jsonl`

files sitting in `~/.claude/projects/`

, one line per event, a `usage`

object on every assistant message.

| Session | Requests | Cache read | Cache write | Output |
|---|---|---|---|---|
| A | 498 | 132M | 2.2M | 0.34M |
| B | 2,138 | 670M | 24M | 1.5M |
| C | 2,652 | 1,191M | 36M | 2.3M |
Total |
5,288 |
1,993M |
62M |
4.2M |

The 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.

Session C is the sharper case. It hit four automatic compactions:

| Trigger | Context size at compaction | Duration |
|---|---|---|
| auto | 968,704 tokens | — |
| auto | 996,078 tokens | 108.7s |
| auto | 999,313 tokens | 139.5s |
| manual | 771,369 tokens | 140.5s |

Every 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.

That'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.

At published list-price API rates, running the actual token mix from these three sessions through the cached-price and never-cached-price formulas gives:

That's an 86% reduction from caching alone — before compaction ever fires.

Two 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):

*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.

But "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.

Nothing 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:

None 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.
