Claude Code token usage: your agent is not burning tokens re-reading your repo
Every session feels like it starts from nothing and re-reads the whole codebase, and the bill keeps climbing.
Where these numbers come from
Measured 2026-08-18 on 22 Claude Code sessions against one repository. Re-run the script at the bottom against your own sessions before trusting any of it.
What we measured
Claude Code writes a transcript of every session to disk, and each assistant turn in it carries the token counts the API billed: uncached input, cache reads, cache writes, and output. Those four are priced differently — by a factor of twenty between the cheapest and the most expensive — so the number of tokens a session used tells you almost nothing about what it cost. We priced all four.
- 22 sessions on one repository — a Next.js frontend, a FastAPI backend, and this marketing site.
- 4,249 assistant turns, 798 million tokens.
- Priced at Claude Opus 5 list rates: $5 per million input, $25 per million output, cache writes at 1.25x input (5-minute TTL) or 2x (1-hour), cache reads at 0.1x.
- The work was done on a subscription, so this is what the same usage would cost at list price — not a receipt.
total
$642.45 across the 22 sessions. Here is where it went.
The bill
| Token class | Tokens | Share of tokens | Cost | Share of cost |
|---|---|---|---|---|
| cache read | 776,820,965 | 97.4% | $388.41 | 60.5% |
| cache write (1h TTL) | 18,147,736 | 2.3% | $181.48 | 28.2% |
| output | 2,901,028 | 0.4% | $72.53 | 11.3% |
| fresh input | 8,111 | 0.001% | $0.04 | 0.0% |
The two columns disagree on purpose. Cache reads are 97.4% of the tokens and 60.5% of the money; output is 0.4% of the tokens and 11.3% of the money. Any advice framed in tokens rather than dollars is optimising the wrong column.
Uncached input was 8,111 tokens
Out of 798 million. Across 4,249 turns. That is one thousandth of one percent, and it is the number that decides this whole question: fresh input is what you pay when the model reads something it has not seen before in this session.
Prompt caching already solved re-reading. The first turn of a session pays to establish context; every turn after it reads that context back at a tenth of the input price. Advice to stop your agent re-reading the repo is advice about a problem the cache closed — and the pages telling you to /clear more aggressively are, as far as this data goes, telling you to throw away the cheap thing.
the actual shape
You are not paying to gather context. You are paying to carry it: 88% of the bill is cache reads plus cache writes, and the model re-reads the whole accumulated conversation on every single turn.
Re-reading the same file is 0.09% of the tokens
We also counted it directly, rather than reasoning about it. Every Read, Grep, Glob and Bash result across the 22 sessions came to 694,823 tokens — against 798 million total. Of those, 35% were repeats: the same file pulled in more than once.
| Most re-read file | Times | Sessions | Tokens |
|---|---|---|---|
| frontend/src/pages/dashboard/dashboard.page.tsx | 23 | 8 | 69,035 |
| frontend/src/components/analyze-modal.tsx | 12 | 3 | 36,074 |
| frontend/src/stores/dashboard/dasboard.store.ts | 25 | 7 | 24,491 |
| frontend/src/components/add-stories-modal.tsx | 6 | 4 | 15,145 |
1,233 distinct read targets; 63 were read more than once, 26 across more than one session. The worst offender in the repo is 69,035 tokens over eight sessions — roughly nine cents at cache-read rates.
So the intuition is real — the agent does open dashboard.page.tsx again every few sessions — but the cost of it is a rounding error. It feels expensive because you watch it happen. The expensive part is invisible.
What a turn costs as the session gets longer
If carrying context is the cost, then a turn should get more expensive as context grows. It does — but not proportionally, which is the useful part. Averaged across the 21 sessions with 20 turns or more, with each session's length normalised so they can be compared:
| Progress through session | Avg context | Avg $/turn | vs first tenth |
|---|---|---|---|
| 0–10% | 78,086 | $0.1375 | 1.0x |
| 30–40% | 160,017 | $0.1292 | 0.9x |
| 50–60% | 195,713 | $0.1263 | 0.9x |
| 70–80% | 237,518 | $0.1593 | 1.2x |
| 90–100% | 297,114 | $0.2717 | 2.0x |
Context grows 3.8x over a session; the price of a turn grows 2.0x. Caching absorbs the rest. The longest session we measured ran 507 turns, grew from 62K to 321K tokens of context, and cost $72.96.
Two things follow. A long session is not disproportionately punished per turn — the sublinear curve is caching doing its job. But every turn is priced against everything the session has accumulated, so total cost tracks turns multiplied by context, and the last tenth of a long session is where the money is.
What actually moves the number
- Fewer turns on the same context. A turn spent re-establishing what the project is costs the same as a turn that ships something. This is the lever with the most room in it.
- Less context carried per turn. Not fewer reads — less accumulated material the model has to hold. Exploration that ends in 180K tokens of context prices every subsequent turn against 180K tokens.
- Check your cache TTL. Our sessions ran entirely on the 1-hour TTL, which costs 2x input to write against 1.25x for the 5-minute one: 2.3% of our tokens, 28.2% of our bill. The 1-hour TTL earns that premium only if your gaps between turns actually exceed five minutes.
- Output is 11.3% of the bill on 0.4% of the tokens. Not the main lever, but the only one where a shorter instruction has a direct, immediate effect.
What does not move it, on this data: read discipline, aggressive /clearing, and anything else aimed at the 0.001% of spend that is uncached input.
What we do not know yet
This is one developer, one repository, one agent, 22 sessions. A team on a monorepo, or an agent run headlessly in CI without a human pausing between turns, may well sit somewhere else entirely. The cache-read share in particular depends on how long your turns are apart, which is a property of how you work rather than of the model.
And the obvious question about our own product is one we have not answered. Entalpa serves a curated, locked spec over MCP, so the reasonable hypothesis is that an agent starting from a spec reaches the same understanding at a smaller carried context than one that explores its way there — which, on these numbers, would be the 88% of the bill rather than the rounding error. We have not measured it. When we have, the result goes on this page whichever way it comes out.
Reproduce it on your own sessions
Your transcripts are already on disk, in ~/.claude/projects/<your-project>/. This prints the same four-class breakdown for them. No dependencies, and nothing leaves your machine.
import json, os, sys
from collections import defaultdict
IN, OUT = 5.00, 25.00 # Claude Opus 5, $ per million tokens
W5M, W1H, READ = IN * 1.25, IN * 2.0, IN * 0.1 # cache write 5m / write 1h / read
totals = defaultdict(int)
for name in os.listdir(sys.argv[1]):
if not name.endswith(".jsonl"):
continue
for line in open(os.path.join(sys.argv[1], name), errors="replace"):
try:
usage = (json.loads(line).get("message") or {}).get("usage")
except ValueError:
continue
if not usage:
continue
created = usage.get("cache_creation") or {}
w1h = created.get("ephemeral_1h_input_tokens", 0)
w5m = created.get("ephemeral_5m_input_tokens", 0)
if not w1h and not w5m: # older transcripts
w5m = usage.get("cache_creation_input_tokens", 0)
totals["fresh input"] += usage.get("input_tokens", 0)
totals["cache read"] += usage.get("cache_read_input_tokens", 0)
totals["cache write 5m"] += w5m
totals["cache write 1h"] += w1h
totals["output"] += usage.get("output_tokens", 0)
rate = {"fresh input": IN, "cache read": READ, "cache write 5m": W5M,
"cache write 1h": W1H, "output": OUT}
for name, tokens in totals.items():
print(f"{name:<15} {tokens:>14,} ${tokens * rate[name] / 1e6:>8.2f}")
print(f"{'total':<15} {sum(totals.values()):>14,} "
f"${sum(totals[k] * rate[k] for k in totals) / 1e6:>8.2f}")Run it as python3 token_burn.py ~/.claude/projects/<your-project>. If your fresh-input number is also near zero, re-reading is not your problem either. Adjust the rates at the top if you are on a different model — the per-million prices are on Anthropic's pricing page.
Questions this raises
Does Claude Code re-read my whole repository every session?
It re-reads files, but you are not billed as though it were new material. Across 22 measured sessions, uncached input was 8,111 tokens out of 798 million — one thousandth of a percent of the total. Prompt caching serves the rest back at a tenth of the input price.
Why is the bill high if prompt caching is working?
Because caching makes carried context cheap per token, not free, and every turn is priced against everything the session has accumulated. In our measurements 88% of the cost was cache reads plus cache writes — carrying context, not gathering it.
Does a longer session cost more per turn?
Yes, but sublinearly. Context grew 3.8x from the start of a session to its end while the average cost of a turn grew 2.0x. Total cost tracks turn count multiplied by carried context, so the last tenth of a long session is the expensive part.
Should I use the 1-hour prompt cache TTL?
Only if your gaps between turns regularly exceed five minutes. It costs 2x the input price to write against 1.25x for the 5-minute TTL. In our sessions those writes were 2.3% of tokens and 28.2% of the bill.
Entalpa gives your agent one locked source of truth
Structured, traceable requirements your agent reads over MCP — so it works from a curated spec instead of reconstructing your project every session. Free to start, no card, and MCP calls never spend credits.