Claude Code writes a log of every session to ~/.claude/projects/. Each line is JSON, and message.usage holds the token counts the API actually returned.
I aggregated 32 sessions. These are not estimates.
96.8% is re-reading conversation history
| Type | Tokens | Share |
|---|---|---|
Re-reading history (cache_read) |
1,370.9M | 96.8% |
| Cache writes | 37.7M | 2.7% |
| Model output | 6.7M | 0.5% |
| What I typed in | 0.2M | 0.01% |
| Total | 1,415.5M | 100% |
My own typing is 0.01%. Shortening prompts optimizes one ten-thousandth of the bill.
The mechanism: the model re-reads the whole conversation every turn. So once a large return enters the context, you keep paying for it on every following turn. Drop a 10k-char return in, talk for 20 more turns, and you paid for 200k chars.
88.8% of that history is tool return values
Not prose. Not your instructions. Tool output.
It is not call frequency. It is return size
| Tool | Share | Calls | Per call |
|---|---|---|---|
| Full page fetch (browser) | 63.3% | 417 | 33,645 chars |
| Reading a whole file | 13.0% | 258 | 11,132 chars |
| Screenshot | 4.0% | 3 | 296,827 chars |
| Bash | 3.7% | 967 | 839 chars |
| Extracting only the values with JS | 0.4% | 164 | 504 chars |
Look at the last two rows.
967 Bash calls cost less than 3 screenshots. One screenshot is ~354 Bash calls.
And in the same browser task, fetching the whole page costs 33,645 chars while extracting just the values you need costs 504. A 67x difference.
Three things that actually move the number
- Never read a whole file. 11,132 chars per read. Grep for the line numbers first, then read that region. Read the whole thing exactly once, when you first need the structure.
- Do not take screenshots out of habit. 296,827 chars each. If the state is readable as text, read it as text.
- Never fetch a whole web page. Extract the handful of values you need. 33,645 becomes 504.
Conversely: stop rationing shell commands. 967 calls came to 3.7%.
Caveats
- This sample skews toward web research, so browser calls rank first. If you mostly write code, file reads will lead. Measure your own logs.
-
cache_readis billed at a lower rate than fresh input, so token share is not cost share. - Whether weekly usage limits deplete in proportion to this split is unverified; the formula is not published.
- Sample: 32 sessions, 2,478 tool returns.
Measure your own
~/.claude/projects/
One folder per project, .jsonl inside. Each line is JSON: message.usage for tokens, tool_result for the returns.
Take the method, not my numbers. Your top consumer will differ, and that is the one worth cutting.
Top comments (0)