Saving Tokens in Claude Code — Measured
Contents
Claude Code burns through tokens faster than you’d expect. There are plenty of tips like “keep CLAUDE.md short” or “use /clear often”, but I wanted to know how much they actually matter, so I measured them.
The one thing to understand
Every time Claude Code sends a request, it resends all of this:
- System prompt + tool descriptions (always there)
- CLAUDE.md (always there)
- The conversation so far, files read, command output (piles up)
A single task usually takes 5–10 requests. So saving tokens comes down to shrinking what’s always there and what piles up.
Repeated parts are cached at about 1/10 the price. That’s cheaper, not free. And once the context fills up, auto-compaction kicks in and earlier details get blurred.
Setup
- A small Python project: 20 files, one planted bug, a 3,000-line log (270 KB)
claude -p "..." --output-format jsonprints token counts and cost as JSON. That’s the measurement- Sonnet 5 unless noted
- Bug-fix runs were repeated 3 times and the median is shown. Everything else ran once, so expect some noise
1. 28K tokens before you do anything
Just “hi”:
| Setup | Input tokens |
|---|---|
| Default | 27,900 |
No tools (--tools "") | 9,100 |
Read-only tools (--tools "Read,Grep,Glob") | 12,100 |
Tool descriptions alone are 19K tokens, sent even for a greeting.
Type /context in a session to see what’s taking up space. It’s the first command to try.
| |
For scripted read-only jobs (summaries, reviews), pass only the tools you need with --tools.
2. Keep CLAUDE.md short
Same bug fix, two CLAUDE.md files:
- Short: 4 lines. The test command and two rules
- Long: 274 lines. A full “handbook” of style rules, review rules, release steps
| Short CLAUDE.md | Long CLAUDE.md | |
|---|---|---|
| Base tokens per request | 28,200 | 46,700 |
| Bug fix cost (median) | $0.117 | $0.218 |
| Result | Fixed | Fixed |
1.9x the cost for the same result. The long file added 18.5K tokens to every request.
Put in:
- Commands Claude can’t guess (test, build, deploy)
- Rules specific to this project (only where it differs from the norm)
- Places not to touch
Leave out:
- Anything the code already shows
- Generic advice (“write clean code”)
- File-by-file descriptions
Move long, occasionally needed procedures into a skill (.claude/skills/<name>/SKILL.md).
As the /context output shows, skills only load a one- or two-line description until
they’re needed. Twelve skills totaled 2.1K.
3. Filter logs before handing them over
“Tell me what the error is and why” on the same log, three ways:
| Method | Input tokens | Cost |
|---|---|---|
cat app.log | claude -p "..." (whole file) | 162,000 | $0.573 |
grep ERROR app.log | claude -p "..." | 30,500 | $0.047 |
| Give the file path and let it search | 90,600 | $0.064 |
All three gave the same answer: the payment gateway didn’t respond within 2 seconds, and with zero retries the charge failed immediately.
Passing the whole file costs 12x more. Giving just the path is fairly cheap because Claude greps on its own. The worst habit is pasting logs or file contents into the chat, which is the same as the first row.
4. /clear after reading something big
Two cases.
Four small questions in one session
Context per request went from 30K to 32K. Barely moved. Cost was about the same as four fresh sessions ($0.102 vs $0.106), thanks to caching.
Read the whole log, then ask one README question in the same session
| Context per request | |
|---|---|
| Same session | 173,800 |
| Fresh session | 30,200 |
A one-line README question drags 170K tokens of log along with it. 5.8x.
So: chaining small tasks is fine; after reading something large or switching topics, /clear.
Caches expire after a while, and then those 170K tokens are sent at full price.
If you need to keep the thread, give /compact instructions:
| |
5. Model and effort
Same bug fix, 3 runs per setting. All succeeded.
| Model | Cost | Time | Requests |
|---|---|---|---|
| Haiku 4.5 | $0.054 | 20.5s | 9 |
| Sonnet 5 | $0.117 | 21.3s | 9 |
| Opus 5.5 low | $0.096 | 13.8s | 6 |
| Opus 5.5 medium (default) | $0.168 | 9.6s | 4 |
| Opus 5.5 high | $0.169 | 9.3s | 4 |
| Opus 5.5 max | $0.241 | 58.1s | 12 |
- Haiku was enough for this bug, and cheapest
- Opus costs more but doesn’t wander; done in 4 requests
- Max was just slow. 6x longer, same result. Max on an easy task is waste
Opus low coming out cheaper than medium is mostly a difference in cache-write cost, not effort itself.
To switch:
| |
A reasonable default: Sonnet or Opus medium day to day, Haiku for simple repetitive work, and raise effort only when you’re actually stuck.
6. Keep MCP tool search on
I attached a fake MCP server with 40 tools:
| Setup | “hi” input tokens |
|---|---|
| No MCP | 27,900 |
| 40 MCP tools, tool search on (default) | 28,500 |
| 40 MCP tools, tool search off | 52,800 |
Current versions don’t preload MCP tool descriptions; they look them up when needed. Only +600
tokens. With ENABLE_TOOL_SEARCH=false you pay +25K tokens on every request.
- Keep Claude Code up to date
- Remove any setting that turns tool search off
- Disable unused servers with
/mcp disable <server> - If there’s a CLI (
gh,aws), prefer it over an MCP server
7. Subagents don’t save money
“Open every module file and summarize it”, done directly vs delegated to a subagent:
| Direct | Subagent | |
|---|---|---|
| Main context at the end | 47,200 | 31,800 |
| Total cost | $0.158 | $0.197 |
The main conversation stayed cleaner, but total cost went up. A subagent starts with its own system prompt.
Use them to protect the main context during long tasks (“find where this is used”), not to cut the bill.
8. Harness setup
Not measured, but worth doing.
One test command
For these tests I made a single ./test.sh and listed it in CLAUDE.md. Claude fixes, runs,
and fixes again on its own. A clear way to verify means less wandering.
Allowlist common commands
.claude/settings.json:
| |
No more clicking approve every time. The tests here ran with --allowedTools "Bash(./test.sh)",
opening only the test command. --dangerously-skip-permissions is convenient but risky.
Formatting via hooks
Run the formatter automatically after every edit, so you don’t spend tokens asking Claude to fix formatting:
| |
Start big tasks in plan mode
Cycle with Shift+Tab until you reach plan mode. You get a plan before any code is touched.
Finding out the direction was wrong after everything’s written is where tokens really go.
Stop early
Esconce: stop the current actionEsctwice: rewind to an earlier point
If it starts opening unrelated files, stopping right away is the cheapest fix.
Check spend
/usage: cost of the current session/context: what’s in the context- In scripts,
--max-budget-usd 1sets a hard cap
Summary
| Do this | Measured |
|---|---|
| Short CLAUDE.md, long procedures as skills | 1.9x cost difference |
| Pass paths or grep output, not whole files | 12x difference |
/clear after big reads or topic changes | 5.8x context difference |
| Haiku for easy work, save max for hard problems | Haiku was 1/3 of Opus medium |
| Keep MCP tool search on | +25K per request when off |
| Subagents protect main context | Total cost +25% |
Run /context once | Shows where tokens go |
One thing that didn’t matter: vague vs specific prompts, in this small project. With only one failing test, a vague prompt found it just as fast ($0.111 vs $0.115). Bigger repos may differ, and naming a file path never hurts.
The biggest wins were trimming CLAUDE.md and not pasting logs. I should probably go look at this blog’s own CLAUDE.md next.