Claude code high token usage is almost always diagnosed as a writing problem, and the first fix people reach for is shorter prompts. We attributed the input side of 20,285 billed turns across 92 sessions and 12 projects between 2026-08-06 and 2026-08-28, using the usage record the API itself writes into every turn. Fresh input — everything typed, plus whatever arrived with it — came to 0.007% of the input side. The other 99.99% is context the model was re-sent.
Key takeaways
- 98.7% of the input side is
cache_read_input_tokens— 4.20 billion of 4.25 billion. That is prior context being read back, once per turn. - The operator typed 47,296 tokens across 450 messages over the same window. The input side was 4.25 billion, an 89,875x multiplier, and typing is 0.0011% of the bill.
- On the eight sessions whose transcripts carry the client's own price, $94.06 bought 1,340 turns — 7 cents a turn, and 1.4 cents per token the operator typed.
- Cost per turn climbs with session depth on its own: 44,278 tokens on turns 1–10 against 382,549 on turn 251 and beyond, an 8.6x rise with no change in the work.
- Session cost correlates with turn count at r = 0.925 and with characters typed at r = 0.453, over the same 92 sessions. Turns are the lever; typing is not.
The short answer
Stop editing your prompts and start counting your turns. On the only corpus we can measure first-hand, what the operator typed was about a thousandth of one per cent of the input side, and the thing that actually predicted a session's cost was how many turns it ran. For how a session is assembled in the first place — what loads, when, and from where — the complete Claude Code guide covers the ground this article assumes.
The per-field split below is in tokens, and it stays in tokens: cache reads, cache writes and fresh input bill at three different rates, so no single rate card converts them. Where the client wrote a real dollar figure into the transcript we quote that instead of estimating one. What a token costs across vendors is a separate measurement, in the most token-efficient AI coding tools; this article is about which line of your own bill is which.
Where Claude Code high token usage comes from
Reports of Claude Code burning tokens usually arrive with a screenshot of a usage dashboard and a theory attached, and the theory is nearly always about the prompt. It is the only part of the exchange the reader authored, so it is the only part that feels like theirs to cut.
Four things arrive on the input side of a request, and only one of them is typed:
- The session prefix. System prompt, tool definitions,
CLAUDE.mdand anything it pulls in. Constant per session, paid on every turn. - The conversation so far. Every prior message and every tool result, re-sent in full so the model can see them.
- Whatever the tools just read. A file read, a search result, a command's output. Usually the largest single addition in an agentic turn.
- What you typed. A sentence or two.
Three of those four grow as a session runs, and none of the three is under the control of prompt hygiene. The official Claude Code cost documentation is explicit that the drivers are conversation length and codebase size, not prompt length — the folk theory survives anyway, because the bill arrives as one number with no attribution attached to it.
Reading one usage record
Claude Code writes every session to a JSONL file under ~/.claude/projects, one JSON object per line. Assistant turns carry the vendor's own billing record:
{
"type": "assistant",
"version": "2.1.247",
"message": {
"usage": {
"input_tokens": 2,
"cache_creation_input_tokens": 325343,
"cache_read_input_tokens": 29490,
"output_tokens": 4
}
}
}
Those four integers are the whole story, and they are documented in the Messages API reference rather than inferred:
cache_read_input_tokens— already in the prompt cache, read back rather than re-processed. Billed at a reduced rate. Billed once per turn.cache_creation_input_tokens— written into the cache on this turn. Billed at a premium, once.input_tokens— everything else on the input side. In an agentic session this is a handful of tokens.output_tokens— what the model generated.
Note what input_tokens is not: it is not "your prompt". Once caching is in play, almost the entire request lands in one of the two cache fields, and what you typed is inside the cached prefix by the next turn. Anthropic's prompt caching documentation describes the mechanism; the consequence for attribution is that the field named "input" is the smallest one.
Almost all of it is one field
npm run check:attribution sums every usage object under ~/.claude/projects by field. Sessions driven by a script rather than a person — earlier articles on this site ran claude -p in a loop with a fixed prompt — are excluded entirely, because they contribute billed turns and no typing at all and would flatter every ratio below. Sixty-eight were excluded; ninety-two remain.
npm run check:attribution
| Field | Tokens | Share |
|---|---|---|
cache_read_input_tokens | 4,195,828,821 | 98.7% |
cache_creation_input_tokens | 54,607,636 | 1.3% |
input_tokens (fresh) | 303,515 | 0.007% |
| Input side, total | 4,250,739,972 | 100% |
| Output | 18,498,426 | 229.8 : 1 |
Two things follow from that table and neither is obvious from a dashboard.
The bill is a re-reading charge. 98.7% of the input side is context that was already assembled and is being paid for again because the model has to see it on this turn as well. That cost scales with the number of turns, because it is charged once per turn regardless of what the turn contains.
Generation is not the expense. 4.25 billion in against 18.5 million out. The model's actual writing — every file it edited, every explanation it produced — is under half of one per cent of the token volume. Optimising what you ask it to write is optimising the small side.
The multiplier between typing and billing
The same scan counts what the operator typed: user turns whose content is a plain string, with tool results, slash-command stubs and command output excluded, converted to tokens at 3.4 characters per token — the figure measured against the live tokeniser in what actually fills a context window, not a rule of thumb.
| Quantity | Value |
|---|---|
| Messages typed | 450 |
| Characters typed | 160,806 |
| Tokens typed | 47,296 |
| Input side | 4,250,739,972 |
| Multiplier | 89,875x |
| Typing as a share of the bill | 0.0011% |
Forty-seven thousand tokens typed. Four and a quarter billion billed on the input side. For every token the operator wrote, roughly ninety thousand were sent.
The ratio is not stable across projects, and the spread is the interesting part:
| Project | Sessions | Turns | Tokens typed | Multiplier |
|---|---|---|---|---|
| project-01 | 24 | 5,214 | 11,036 | 108,726x |
| project-03 | 13 | 3,240 | 15,722 | 51,385x |
| project-08 | 2 | 582 | 45 | 2,618,112x |
| project-12 | 2 | 61 | 265 | 10,603x |
project-08 is two sessions in which forty-five tokens of instruction produced 582 billed turns. That is not an anomaly to be filtered out — it is the modern shape of the tool. A short instruction that authorises a long autonomous run is the most expensive sentence you can write, and it is also the shortest.
What a typed token actually cost
Recent Claude Code sessions write one more line we did not expect to find: a cost-state record holding the client's own totalCostUSD and a per-model modelUsage breakdown. It is a new addition, so most of this corpus predates it — 8 of 92 sessions carry one. Those eight are the only place in this article where a dollar figure is read rather than estimated.
| Measure | Value |
|---|---|
| Sessions with a recorded price | 8 of 92 |
| Billed turns in them | 1,340 |
| Total, as the client recorded it | $94.06 |
| Per turn | $0.0702 |
| Per token the operator typed | $0.0142 |
| Per million input-side tokens | $0.459 |
Seven cents a turn, and a cent and a half for every token typed into them. The second figure is the one worth keeping: at 1.4 cents per typed token, the sentence you are reading would cost roughly a dollar to have written as an instruction — not because the sentence is expensive, but because of everything a sentence sets in motion.
Why shorter prompts do not help
Every guide that promises to reduce Claude tokens opens with prompt hygiene: be concise, drop the pleasantries, stop explaining yourself. All of it is fine advice for being understood. None of it is a cost lever, and the arithmetic is not close.
Halving everything the operator typed over these three weeks would remove 23,648 tokens from an input side of 4.25 billion. That is 0.00056% of the bill. Rounded to any number of decimal places a dashboard displays, it is zero.
The reason is structural rather than accidental. What you type is paid for once at full rate, then folded into the cached prefix and paid for again at the cache rate on every subsequent turn — but it is a sentence inside a prefix that also holds the system prompt, the tool definitions, your instruction files and every tool result so far. Its share of that prefix is tiny on turn one and smaller on turn fifty.
The same logic explains why the phrasing advice feels like it works. Shortening a prompt often makes the agent do less — fewer searches, fewer files, fewer turns — and that is what moves the number. The saving comes from the work avoided, not from the characters removed, which is why "be concise" sometimes helps a lot and usually helps not at all.
The three levers that do
Bucket every turn by how deep into its session it was, and the driver becomes visible:
| Turn index | Turns | Input tokens per turn |
|---|---|---|
| 1–10 | 891 | 44,278 |
| 11–25 | 1,256 | 67,215 |
| 26–50 | 1,989 | 104,465 |
| 51–100 | 3,716 | 148,130 |
| 101–250 | 9,144 | 230,800 |
| 251+ | 3,289 | 382,549 |
Monotone, and 8.6x from the first bucket to the last. A turn deep in a session costs nearly nine times what the same turn costs at the start, because it carries everything before it. Nothing about the request changed; only its position did.
Two correlations over the same 92 sessions confirm which variable that is. Session input side against turn count: r = 0.925. Against characters typed: r = 0.453. The gap of 0.472 is the whole argument, and it is guarded in the check rather than left in prose — if a future corpus closes it, the script exits 1 and says the article needs re-checking.
So the levers, in order of how much they move:
- Fewer turns per session. Turn count is what the re-reading charge multiplies. One well-scoped request that runs twenty turns costs a fraction of the same work discovered across two hundred.
- A smaller prefix. Every byte of
CLAUDE.mdand everything it pulls in is re-sent on all of them. That is the mechanism behind the CLAUDE.md cause of a slow Claude Code session, and it is why an instruction file that grew quietly shows up as a cost you cannot place. - Starting fresh instead of continuing. A new session resets the depth counter to one. Carrying a finished task into the next one pays 382,549 a turn for context that stopped being relevant an hour ago — and on this machine the window never came back down on its own in 89 sessions. When you need continuity without carrying bloated turn history, use the Claude Code /compact command to compress context.
If what you are actually hitting is a wall rather than a bill, the limits themselves work differently and are covered in how AI coding rate limits actually work.
Run the attribution yourself
node scripts/check-token-attribution.mjs --remeasure
--remeasure re-reads ~/.claude/projects and rewrites the committed fixture; without it the check reads the fixture, so it stays reproducible on a machine with no transcripts. That directory is the whole evidence base for this article, and it is swept after 30 days by default — measure before it goes. --json prints the whole measurement. The scan reads four integers, a timestamp, one optional cost figure and the length of your own typed messages, and records no project name, no path and no prompt or response text.
Three things to get right if you write your own rather than borrowing this one:
- Count all three input fields. Attributing only
input_tokensproduces a number 14,000 times too small and a conclusion exactly backwards. - Exclude scripted sessions. Anything driven by
claude -pfrom a shell loop has billed turns and no typist, so it inflates the numerator of every ratio and touches no denominator. - Separate typed messages from tool results. Both arrive under the user role. Only one of them was typed, and conflating them is the difference between measuring a person and measuring a file read.
What did not work
The first corpus was almost entirely machine, and it gave two answers. The obvious scope was this project's own transcript directory: 70 sessions, 754 billed turns, 123,863,049 tokens on the input side. Sixty-eight of those seventy sessions were claude -p probes written by earlier articles' scripts, each piping a large file to stdin exactly as a person pasting it would. Count that stdin as typing and the multiplier is 175x. Exclude it and keep the turns and the multiplier is 232,825x. Same 754 turns, two answers three orders of magnitude apart, and the article's headline number would have been whichever one got measured first. The fix was to drop probe sessions whole — turns and typing together — by a rule in the script rather than by eye, and to widen the corpus to every project on the machine so that no single scripted experiment could dominate it.
We asserted an absence and it was not there. The first version of this article said the transcripts record tokens and not prices, and the script's header said so too. Both were wrong: enumerating every distinct line type in the corpus rather than the ones we expected turned up cost-state, carrying the client's own totalCostUSD on eight sessions. The claim was not merely imprecise — it was the kind that stops anyone from looking, which is the worst kind to publish. The section above exists because the assertion was checked before it shipped rather than after. What survives of the original point is narrower and true: there is no per-field price, because the three input fields bill at three rates the record does not split.
The correlation guard was nearly one number. The first draft of the check asserted only that cost correlates with turn count at r ≥ 0.8. That guard stays green in a world where typing correlates just as hard — which would destroy the article's argument while the check reported success. What the claim actually needs is the margin between the two correlations, so the guard asserts the gap. This is the same failure the last three articles here hit: an accepted value written from the conclusion rather than from the thing the conclusion depends on.
Best practices for token usage
- Count turns, not words. Turn count is what the per-turn re-reading charge multiplies, and it is the number that predicted session cost at r = 0.925 here.
- Scope a request so it finishes in one pass. The expensive pattern is discovering the task across two hundred turns, not describing it in two hundred words.
- Start a new session when the task changes. Depth resets, and the first ten turns of anything cost about an eighth of what turn 251 costs.
- Audit every file that loads at launch, by bytes. It is re-sent on every turn of every session, so its cost is multiplied by your turn count for as long as it exists.
- Read your own
usagerecords before believing any advice about this, including ours. The attribution takes a minute and it is your bill, not a benchmark.
Common mistakes with token usage
- Rewriting prompts to save money. Tempting because the prompt is the only part you authored. Symptom: weeks of terser instructions and an unchanged bill. Fix: measure the share first — it was 0.0011% here.
- Reading
input_tokensas "what I sent". The field name invites it. Symptom: a total that is thousands of times too small and a belief that the tool is cheap. Fix: sum all three input-side fields, cache reads included. - Leaving one session open all day. Feels efficient because the context is warm. Symptom: turns that cost eight times what they cost at breakfast. Fix: end a session when its task ends.
- Blaming the model or the release. Both are legible and neither was the variable here. Symptom: a downgrade that changes nothing. Fix: check what your own repository and your own session lengths did first, the way we did across seventeen versions.
What we are not claiming
⚠️ This is one operator on one machine. The corpus spans 12 projects and three weeks, but every turn came from the same person with the same working habits. The direction is what we would expect to generalise; the exact multiplier is ours.
⚠️ The per-field table is not a price. The three input-side fields bill at three different rates, so converting any of those token figures to money produces an answer that is wrong in a direction this data cannot report. The only dollars here are the eight sessions where the client recorded its own, and they are a session total per model rather than a breakdown.
⚠️ The typed figure is characters counted exactly and then converted. The conversion carries the measured error of the 3.4 chars-per-token constant. At a multiplier of 89,875x, a 10% error in the divisor does not change any sentence in this article.
⚠️ The corpus includes the sessions that produced this article, which are exactly the long autonomous kind the piece is about. Re-running --remeasure returns different figures. The fixture is a dated snapshot; the guards are directions and margins, which is what survives the drift.
Conclusion
If Claude Code token usage looks high, the answer is in your own transcripts and it is not your prompts. Across 20,285 billed turns, 98.7% of the input side was context being re-read, 0.007% was fresh input, and session cost tracked turn count more than twice as hard as it tracked anything typed. Where a price was recorded at all, it came to seven cents a turn. The lever is how many turns you run and how much prefix each one carries.
Run check:attribution over your own sessions, then go and weigh the files that load before you type anything. For what a token costs once you know how many you are spending, read the most token-efficient AI coding tools; for why the prefix is the dominant term at all, what actually fills a context window.
Frequently asked questions
Why is Claude Code using so many tokens?
Do shorter prompts reduce Claude Code token usage?
What is cache_read_input_tokens in Claude Code?
Does a long session cost more per turn than a short one?
How do I check my own Claude Code token usage?
Muhammad Kashif
Founder and editor of Devventa, covering AI coding assistants, Next.js and the modern AI development stack.




