How to reduce Claude Code token usage without losing context

The tactics that actually move the number, and the ones that quietly make things worse.

The short answer: most of what you pay for in Claude Code is not the code you asked it to write. It is the same conversation prefix being re-sent on every turn. So the highest-leverage changes are the ones that keep that prefix cacheable and keep it small. In practice that means avoiding mid-session edits to files that sit at the front of the prompt, cutting the fixed overhead of MCP tool definitions and memory files, ending sessions instead of letting them sprawl, and pushing the small mechanical calls onto a cheaper or local model. None of that requires giving the model less context about your actual problem.

The tactics people reach for first tend to be the bad ones. Shortening your prompts saves a rounding error. Telling the model to be terse saves output tokens, which are a minority of the bill on a long agent run. Aggressively compacting every few minutes feels productive and often costs more than it saves, because each compaction is itself a large call and it invalidates everything cached behind it. Below is where the tokens really go and what to do about each bucket.

Where the tokens actually go on a coding agent run

An agent turn is not one request. A single instruction like fix this failing test can produce a dozen model calls: read a file, grep, read another file, run the test, read the output, edit, re-run. Every one of those calls re-sends the entire conversation so far, plus your system prompt, plus every tool definition, plus whatever memory files got loaded. The transcript grows monotonically, so call number twelve is carrying the weight of calls one through eleven.

That is why input tokens dominate. A run that produced 400 lines of diff might have moved several million input tokens. It is also why prompt caching matters more than anything else on this list: Anthropic charges cache reads at a small fraction of the normal input rate, with a modest premium on the write. If your prefix stays stable, those twelve calls mostly hit cache. If it does not, you pay full freight twelve times over.

Claude Code has a /context command that shows the breakdown of what is currently occupying the window: system prompt, tools, memory files, conversation. Run it on a session that feels expensive. The number that surprises people is almost never the conversation.

Protect the cache prefix

Caching works on prefixes. Anything you change near the front of the prompt invalidates everything after it. A few habits break the prefix without anyone noticing:

  • Editing CLAUDE.md mid-session. It sits near the front. Change one line and the next call is a full cache miss on everything.
  • Adding or removing an MCP server while a session is open. Tool definitions live in the prefix too.
  • Switching models mid-session. Caches are per model, so you start cold on the new one.
  • Long idle gaps. The default cache lifetime is short, measured in minutes, so a coffee break between prompts means the next turn pays a write again.
  • Injecting anything time-varying into the system prompt or a memory file. A timestamp or a changing git branch line at the top of CLAUDE.md guarantees a miss on every single call.

The practical rule is to do your configuration changes between sessions, not during one, and to batch related work so the expensive prefix gets amortised over more turns rather than rebuilt for each one.

Cut the fixed overhead before you cut context

Every MCP server you have connected contributes its full tool schema to every request, forever, whether or not the current task touches it. Ten servers with a dozen tools each is a meaningful standing tax paid on every call of every session. I audit mine roughly monthly and disable the ones I have not used. A browser automation server is worth its weight on a frontend day and is pure overhead on a database migration day.

The same goes for memory files. CLAUDE.md is loaded on every request. A 900-line house style document that covers seven languages you do not use in this repo is being re-read by the model thousands of times a week. Keep the project file to what is genuinely non-obvious about this codebase: the commands to run, the conventions a newcomer would get wrong, the directories that are load-bearing. Push the rest into skills or docs that get pulled in on demand.

Subagents help here for a different reason. A subagent gets its own context window, does the exploratory reading, and returns a summary. The expensive part of a codebase search never lands in your main transcript, so it never gets re-sent on every subsequent turn. Delegating a wide search is usually cheaper than doing it inline even though it looks like more work.

Compact on purpose, clear more often than you think

Compaction summarises the conversation so far and rebuilds the window from that summary. It is a real call against a large input, and it throws away the cache. Auto-compaction firing repeatedly during a long session is a common source of a bill nobody can explain.

The cheaper habit is to finish tasks and start fresh. If you are done with the auth refactor and moving to a CSS bug, clearing the session costs nothing and drops your per-call baseline back to the floor. Carrying the auth transcript into the CSS work does not help the model and you pay for it on every turn. When you do need continuity across a clear, write the state down: a short handoff note in a scratch file is a few hundred tokens read once, versus tens of thousands re-sent indefinitely.

If you must compact, do it at a natural boundary you choose, right after a milestone, rather than letting it trigger in the middle of a debugging chain where the details it discards are the ones you still need.

Send the cheap work somewhere cheap

A lot of agent traffic is not reasoning. It is summarising a diff, generating a commit message, classifying whether a file is relevant, formatting output. Those calls do not need a frontier model and often do not need the network at all. A mid-size local model on Ollama or LM Studio handles them at zero marginal cost, and the cloud model stays for the work that actually needs it.

The honest caveat is that local routing is not free of risk. A weak local answer that silently passes through is worse than an expensive correct one, so whatever you use needs a retry path back to the cloud when the local response looks thin. Same story with caching a coding agent: caching an ordinary text completion is safe, and caching a response that carries a tool call is not, because replaying a stale tool call corrupts the run.

Measure before you optimise, which is where Probe0 comes in

I built Probe0 because I could not answer a simple question: which of my agents spent that money, and on what. Claude Code, Codex, and Cursor were all running on the same machine and the only signal I had was a monthly total going up.

Probe0 is a local proxy. It runs entirely on your machine, there is no Probe0 server, and every coding agent CLI on the box routes through it after one setup step: the proxy plus a certificate installed once, no per-tool configuration. Recording gives you the ledger the tactics above need, with model, token counts, real cost, latency, and which process made each call. The modules are individually switchable and each reports what it saved: Local Routing to a model already running in Ollama or LM Studio with weak answers auto-retried on the cloud, Model Tiering to try a cheap model first, an Exact Cache on local disk that never touches the network, a Semantic Cache with a strict similarity floor that refuses to match anything carrying tool calls, Request Coalescing so simultaneous identical calls collapse into one upstream, and a Spend Guard with a hard cap per run and per day that warns and then pauses. Because it knows your actual usage, it can also tell you when you are paying for a plan tier above what you use.

The limits are worth stating plainly. It is macOS only and in private beta. It is a single-developer tool, not a team gateway with multi-user deployment. Provider coverage is what coding agents call, not a hundred-provider catalogue. If you need a hosted gateway with org-wide keys and shared dashboards, a service like Portkey or Helicone is the right shape and Probe0 is not.

The cheapest token is the one you never sent twice. The second cheapest is the one you sent to a model already running on your laptop.

If you want to start without installing anything, ccusage reads the JSONL transcripts Claude Code already writes to disk and gives you a per-session cost breakdown. It is a good first look. It only sees Claude Code, and it reads logs rather than sitting in the request path, so it can tell you what happened but cannot change what happens next. That gap is the reason a proxy exists.

Related