Optimizing token usage with Claude Code and Copilot: what actually works

Cutting token usage isn't only about cost. A context cluttered with irrelevant content doesn't just cost more: it also dilutes what actually matters within the context window, degrading response quality well before hitting any technical limit. The techniques below serve both goals at once, not just the bill.
The levers, at a glance
| Lever | What it saves | Cost of ignoring it |
|---|---|---|
| Targeted reads (grep, offset/limit) instead of whole files | Input tokens on every read | Thousands of irrelevant lines loaded for a single function |
| Prompt caching (stable prefix) | Up to 90% on cached tokens | Full rewrite of the stable context on every call |
| Sub-agents for broad exploration | Main context preserved | The main conversation bloats with disposable intermediate results |
| Not re-verifying what the tool already guarantees | An entire read avoided | Systematic re-reading after every edit, with no added value |
| Independent tool calls in parallel | Number of round trips | Context retransmitted on every sequential turn |
| Stable preferences in memory/CLAUDE.md | Repetition in every prompt | The same reminder rewritten by hand in every conversation |
Prompt caching, explained simply
Anthropic's caching mechanism works on a stable prefix: the part of the context that doesn't change from one call to the next (system instructions, project structure, reference files) can be marked as cacheable. The first call pays a write surcharge, but every following call that reuses that exact same prefix reads from cache at roughly 10% of the normal rate, as long as the cache hasn't expired.
| Cache duration | Write surcharge | Read discount |
|---|---|---|
| 5 minutes | 1.25x standard rate | −90% |
| 1 hour | 2x standard rate | −90% |
This mechanism explains why the position of content in a conversation matters: a system prompt and a CLAUDE.md placed up front, unchanged from turn to turn, benefit from the cache. A context rebuilt differently on every call (files in a different order, reformatted content) invalidates the prefix and pays the full rate every time, without you necessarily noticing unless you watch the bill.
Targeted reads instead of whole files
The most common temptation is to load an entire file to answer a question
that only concerns one function. On a file with several thousand lines,
grep to locate the symbol first, followed by a read limited to the
relevant lines, costs a fraction of a full read, for an identical result on
the question actually asked.
# Expensive: loads the whole file, including 1,900 irrelevant lines
read src/services/billing.ts (2000 lines)
# Targeted: locate first, then read only the relevant section
grep "calculateInvoice" src/services/billing.ts
read src/services/billing.ts, lines 340-410
Sub-agents as a partition, not just parallelism
The most underrated benefit of sub-agents isn't parallel execution speed, it's context isolation. A broad codebase search ("where is this behavior configured?") may require exploring dozens of files before finding the right answer. Delegating that exploration to a sub-agent, which returns only its conclusion, keeps the main conversation from accumulating every intermediate result that no longer has any value once the answer is found.
Trusting what the tool already guarantees
A common trap: systematically re-reading a file after modifying it, out of excess caution. If the edit tool confirms the operation succeeded, that re-read adds no new information, it just pays twice for content already known. Verification makes sense when a result is genuinely uncertain, not as a systematic reflex.
The special case of Copilot: context isn't just the prompt
On GitHub Copilot, there's no explicit user-facing cache control, but the same principle applies in a different form: every file open in the editor influences the suggestion, not just the active one. Closing files unrelated to the current task, keeping functions short and well-named, and replacing long chat exchanges with a precise comment in the right place in the code reduces what has to be factored into each suggestion, with an effect similar to a more targeted context on the conversational agent side.
What optimization should never sacrifice
All these techniques aim to remove what serves no purpose, never to cut what's genuinely needed for the task. A context compressed so tightly that it forces the assistant to guess at missing information always ends up costing more overall, in correction iterations, than a slightly more generous but correct-on-the-first-try context. The goal isn't to minimize tokens at all costs, it's to only pay for what actually adds value to the answer.