Anthropic Prompt Caching Tutorial: cache_control, TTLs, and Real Costs
A practical guide to Claude prompt caching: how cache_control breakpoints work, 5-minute vs 1-hour TTL math, write premiums, common mistakes that zero your hit rate, and how to keep the cache warm.
Claude bills cached prompt tokens at roughly 10% of list price — but unlike OpenAI and Gemini, Anthropic's caching is explicit: nothing is cached until you mark it. This tutorial covers the mechanics that actually determine whether you collect the discount: breakpoints, TTL selection, the write-premium math, and the failure modes that silently zero hit rates in production.
The mental model
You place up to four cache_control markers in a request. Everything from the start of the prompt up to each marker becomes a cacheable prefix block. On the next request, if that prefix matches byte-for-byte, those tokens are billed as cache reads (~10%) instead of fresh input (100%). Order matters for hit probability, so structure prompts stable-first:
- Tools — schemas change rarely; keep serialization order deterministic.
- System prompt — instructions, policies, few-shot examples.
- Conversation history — grows per turn; a breakpoint after the last complete turn lets each turn extend the cached prefix.
- The new user message — always fresh; never cache-marked.
The pricing math
Three billing rates exist per model:
- Cache write: 1.25x input price (5-minute TTL) or 2x (1-hour TTL) — charged when a prefix block is stored.
- Cache read: ~0.1x input price — charged when a prefix block hits.
- Plain input: 1x — everything uncached.
The break-even is forgiving: a 5-minute write costs 25% extra once, and each subsequent hit saves ~90%. A prefix reused even twice within its TTL is strongly profitable. The trap is the other direction — if your requests arrive further apart than the TTL, you pay the write premium on every call and never collect a read. We measured this on our public benchmark: on support-style traffic with 6–9 minute gaps, hand-tuned breakpoints were more expensive than no caching at all, while keeping the cache warm through the gaps came out 67% cheaper than direct.
Choosing the TTL — with real traffic, not vibes
The decision variable is your median inter-request gap per key:
- Gap < 5 min → 5-minute TTL. Cheapest writes; every hit refreshes the clock.
- Gap 5–60 min → either the 1-hour TTL (2x writes, but they survive the gaps) or a warmed 5-minute cache (tiny keep-alive pings, each costing a fraction of a re-write). Which wins depends on prefix size and gap distribution — it's arithmetic, not preference.
- Gap > 1 h → caching cross-request prefixes rarely pays; cache within bursts only.
The five mistakes that zero your hit rate
- No breakpoints at all. SDK defaults don't add
cache_control. If you've never set it, your hit rate is 0% and nothing in the response tells you. - A timestamp in the system prompt. “Current time: 14:32:07” changes every call, and everything after it can never match. Move volatile context to the end, or truncate to the hour if the model truly needs it.
- Nondeterministic serialization. Tool lists built from an unordered map reorder randomly between processes — byte-exact matching fails invisibly.
- Breakpoint placed too early. Marking only a 200-token system stub caches 200 tokens and re-bills the 5,000-token tool schema above… nothing. Mark the largest stable prefix, not the smallest.
- Fleet cold starts. Deploys and prompt edits invalidate everything at once; the first call per conversation after a release pays write price. Expected — but it means hit rate must be judged as a trend, not a point value.
Measuring: the number Anthropic reports and the one it doesn't
Every response's usage block reports cache_creation_input_tokens and cache_read_input_tokens — your ground truth. What no provider reports is the counterfactual: tokens that should have been cached but weren't, i.e. the money you're leaving on the table. That's the number worth alerting on, and computing it requires comparing each request's prefix against what was cacheable — tedious by hand, mechanical for a proxy.
Automating all of the above
Everything in this guide is deterministic policy, which is why we built Caching.ai as a drop-in proxy: it injects cache_control on the largest stable prefix, flags cache-breakers with the likely cause, chooses 5-minute vs 1-hour TTL from your measured gap distribution, keeps prefixes warm only while the ping cost stays below the re-write cost, and shows hit rate, saved dollars and wasted dollars per key. One base-URL swap; 20% of verified savings; free under $5/month. The broader mechanics across providers are in What is prompt caching?, and the full cost playbook is in How to reduce LLM API costs.
Frequently asked questions
How much does Anthropic prompt caching cost?
Cache reads are billed at roughly 10% of the model's input price. Writes carry a premium: about 1.25x input price for the 5-minute TTL and 2x for the 1-hour TTL. One cache hit within the TTL already outweighs the write premium several times over.
Why is my Claude cache hit rate 0%?
The most common causes, in order: no cache_control breakpoints set at all (SDK defaults don't add them), something unstable at the top of the prompt (timestamp, request ID, reordered tools) breaking the byte-exact prefix match, a prefix below the model's minimum cacheable length, or requests arriving further apart than the TTL so every entry expires before it's reused.
Should I use the 5-minute or 1-hour cache TTL on Claude?
Compare your median gap between requests to the TTL. If calls arrive within 5 minutes of each other, the 5-minute TTL's cheaper write premium (1.25x vs 2x) wins. If gaps run longer — support traffic, sparse agents — the 1-hour TTL or keeping the 5-minute cache warm with tiny pings is cheaper than re-writing on every call. The right answer follows from measured traffic, not guesswork.
Does prompt caching work with streaming and tool use on Claude?
Yes. Caching applies to the prompt prefix regardless of whether the response streams, and tool definitions are part of the cacheable prefix — in fact tools plus system prompt are usually the largest stable block you have. Keep tool ordering deterministic or the prefix changes every call.