How it works

Caching is free. Keeping it working isn't.

Anthropic already gives you a 90% discount on repeated context. The hard part is that nothing tells you when you stop receiving it.

The mechanism

What a cache hit actually is.

Your request is a prefix — tools, then system prompt, then message history. If that prefix is byte-identical to one Anthropic has seen recently, it serves the stored computation instead of redoing it.

toolssystem historythis turn

The model reads the identical token sequence either way. A cache hit changes billing and latency only — never what Claude computes. That's why there's no quality question to argue about, and no eval to run.

Why it breaks

Four ways teams lose the discount.

None of these raise an error. In every case the request succeeds, the answer is correct, and the invoice quietly grows.

A moving field in a stable place

A timestamp, a session id, a live to-do list or an evolving scratchpad inside the system prompt. The prefix differs every turn, so nothing before it can ever match.

Overshooting the lookback

A breakpoint searches back at most twenty content blocks. A turn with eight parallel tool calls contributes about sixteen on its own — and the next request never reaches the last write.

Churning the tool list

Tools render before everything else, so adding, removing or reordering one invalidates tools, system and messages together. An MCP server reconnecting mid-session does it too.

Falling under the minimum

Below the model's minimum cacheable prefix — 512 tokens on Opus 5, more on older models — caching is skipped entirely. No error, both cache fields simply read zero.

What good looks like

The fix is structural, not clever.

ProjectDiscovery published exactly how they went from 7% to 84%. Every move is the same shape: keep the stable things stable, and push everything that changes to the tail.

Three breakpoints, deliberately placed

Static system prompt on a 1-hour TTL. Tool definitions sorted alphabetically, dynamic subagents last, also 1-hour. A sliding 5-minute breakpoint on the newest tool result, so only the new turn is ever recharged.

The relocation trick

Working memory, skills and runtime context moved out of the prefix and into a single message at the tail. That one change took them from 7% to 74%.

Placeholders over values

Template variables rendered as [provided in Runtime Context] rather than the actual value, so the same prefix is cacheable across every user instead of once per user.

Freeze the clock

A date with no time in it stays byte-identical all day. A timestamp with minutes in it invalidates the prefix on every single request.

The 20-block trap has a fix too. Because a breakpoint only looks back twenty blocks, they placed intermediate marks every eighteen — extending usable reach to roughly fifty-four blocks without exceeding the four-breakpoint limit. Techniques and figures from their write-up.

The audit

What happens when you run it.

Read-only, on your side, over usage you already have. Nothing is proxied and no prompt text is read.

Point it at your usage

Local transcripts, or your organisation's usage report via an admin key. Either way it reads token counts, model ids and timestamps — never message content.

Measure the real hit rate

Cache reads divided by cacheable input. This is a measurement, not an estimate — the numbers come from Anthropic's own usage fields on every response you've already had.

Price the gap

What your traffic cost, against what the same traffic costs at a healthy hit rate. The difference is your headroom, in dollars, per month.

Get the diagnosis

Which projects are leaking, and which of the four failures above is doing it. If the headroom is under 20%, we say so and stop there.

The honest limit. Caching discounts input tokens only — output always bills at full rate. If your workload is mostly generation rather than context, your ceiling is lower, and the audit will show you that rather than talk around it.