Anthropic prompt caching lets the Claude API reuse a prompt prefix you have already sent, so repeated context such as a long system prompt, tool definitions or a reference document is billed at a fraction of the normal input price on later requests. You turn it on by adding cache_control to the content you want cached, and you confirm it works by reading the cache fields in the response usage object.
Who this is for and what you will have
This guide is for developers whose Claude requests share a large, stable beginning: a long instruction set, a few thousand tokens of tool definitions, a document users ask many questions about, or a growing conversation. By the end you will know where to put the cache breakpoint, which TTL to choose, how to calculate whether caching saves money, how to read the usage fields, and what silently breaks a cache.
How prompt caching works
Caching covers a prefix of the request. The prefix is built in a fixed order: tools, then system, then messages. When you mark a block with cache_control, everything up to and including that block becomes eligible for the cache. On the next request, if the prefix is identical, Claude reads it from the cache instead of processing it again.
Two rules from the documentation shape everything else:
- A cache hit needs a 100 percent identical prefix, including text and images.
- A cache write happens only at a breakpoint, and each breakpoint looks back up to 20 blocks for an earlier write.
The only cache type is ephemeral. You can use up to 4 explicit breakpoints per request, and breakpoints themselves are free.
Prerequisites
You need an Anthropic API key, the Python SDK (pip install anthropic) and a prompt that is long enough to cache. Minimum cacheable lengths vary by model, and shorter prompts are processed without caching and without an error.
| Minimum length | Models (from the documentation) |
|---|---|
| 512 tokens | Fable 5.1, Mythos 5.1, Opus 5.5, Opus 5, Sonnet 5.5, Fable 5, Mythos 5, Haiku 5.5 |
| 1,024 tokens | Opus 4.8, Sonnet 5, Sonnet 4.6, Sonnet 4.5, Opus 4.1, Opus 4, Sonnet 4 |
| 2,048 tokens | Mythos Preview, Opus 4.7, Haiku 3.5 |
| 4,096 tokens | Opus 4.6, Opus 4.5, Haiku 4.5 |
If your cached content is shorter than the minimum for your model, nothing is cached and the usage fields show zero for both cache fields.
Step 1: Add a cache breakpoint
The simplest pattern is to put the stable material in the system array and put cache_control on the last stable block. The example below caches a long policy document that every request shares.
import anthropic
client = anthropic.Anthropic()
POLICY_TEXT = open("support_policy.txt", encoding="utf-8").read()
def ask(question: str):
return client.messages.create(
model="claude-sonnet-5-5",
max_tokens=512,
system=[
{
"type": "text",
"text": "You answer questions using only the policy below.",
},
{
"type": "text",
"text": POLICY_TEXT,
"cache_control": {"type": "ephemeral"},
},
],
messages=[{"role": "user", "content": question}],
)The user question comes after the breakpoint, so it changes per request without disturbing the cached prefix.
Automatic caching
The documentation also describes automatic caching: add a single top-level cache_control field to the request and the system moves the breakpoint to the last cacheable block as a conversation grows. This suits multi-turn chat, where each turn extends the previous one.
{
"model": "claude-sonnet-5-5",
"max_tokens": 1024,
"cache_control": {"type": "ephemeral"},
"system": "You are a helpful assistant.",
"messages": [{"role": "user", "content": "..."}]
}Automatic caching uses one of your four breakpoint slots. If you also place an explicit cache_control on the last block with the same TTL, the automatic one becomes a no-op. A different TTL on the last block returns a 400 error, and so does a request that already has four explicit breakpoints. Check that your SDK version exposes the top-level field before relying on it; the explicit block form above works regardless.
Step 2: Choose a TTL
| TTL | Syntax | Write price | Notes |
|---|---|---|---|
| 5 minutes (default) | {"type": "ephemeral"} | 1.25 times base input | Refreshed at no cost on each hit |
| 1 hour | {"type": "ephemeral", "ttl": "1h"} | 2 times base input | Costs more to write; suits gaps longer than five minutes |
The lifetime is measured from the start of the request that writes or reads the entry, so a long streaming response eats into it. When you mix TTLs in one request, 1-hour entries must come before 5-minute entries. Both TTLs have the same latency benefit, so the choice is purely about how often the prefix is reused.
Step 3: Check whether caching pays off
For models where a cache read costs 0.1 times the base input price, the arithmetic is simple. Let base input be 1 unit per prefix:
- Two requests with no caching cost 2.0.
- Two requests with the 5-minute cache cost 1.25 for the write plus 0.1 for the read, which is 1.35.
- With the 1-hour cache, two requests cost 2.0 plus 0.1, which is 2.1, so you need at least two reads before it beats no caching (2.2 versus 3.0 across three requests).
The per-million-token prices below come from the pricing table on the caching page at the time of writing. Check the page before you budget, because prices and model lineups change.
| Model | Base input | 5-minute write | 1-hour write | Cache read |
|---|---|---|---|---|
| Claude Opus 5.5 | $4 | $5 | $8 | $0.20 |
| Claude Sonnet 5.5 | $2 | $2.50 | $4 | $0.10 |
| Claude Haiku 4.5 | $1 | $1.25 | $2 | $0.10 |
Note that Opus 5.5 and Sonnet 5.5 list a read multiplier of 0.05, not 0.1, so the saving is larger there. Cache writes and reads stack with other modifiers, such as the Batch API discount and long-context pricing.
Step 4: Verify with the usage fields
Print the usage object after each call.
r1 = ask("What is the refund window?")
print(r1.usage)
r2 = ask("Who approves exceptions?")
print(r2.usage)The fields to watch:
cache_creation_input_tokens: tokens written to the cache by this request.cache_read_input_tokens: tokens read from the cache.input_tokens: tokens after the last breakpoint, which were not cached.cache_creation: a breakdown intoephemeral_5m_input_tokensandephemeral_1h_input_tokens.
Total input is the sum of the first three fields:
total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokensOn the first call you should see a large cache_creation_input_tokens. On the second call within the TTL, cache_read_input_tokens should hold roughly the same number and input_tokens should be small. If both cache fields are zero, the prompt was not cached, usually because it fell below the minimum length.
Step 5: Avoid what invalidates the cache
Changes at one level invalidate that level and everything after it, in the order tools, system, messages.
Editing any tool definition (names, descriptions or parameters) invalidates the tools, system and messages caches. Changing tool_choice invalidates cached message blocks, while tool definitions and the system prompt stay cached. The documentation lists further settings that affect the cache, including toggling web search or citations, adding or removing images, the speed setting, and the thinking and effort configuration, so check its invalidation table before changing them mid-conversation. The practical lesson is to keep the early part of the prompt byte-identical.
Other common causes:
- Timestamps, request IDs or per-user values placed before the breakpoint. Move them after it.
- Reordered content. Keep the same order every time.
- Non-deterministic JSON key ordering in
tool_useblocks, which the documentation notes is common in Swift and Go. - Concurrent requests. They get no cache hits until the first response has started, so send one request first when you need to warm a cache.
Pre-warming a cache
You can write the cache before real traffic arrives by sending max_tokens: 0 with the breakpoint on the shared prefix. The request writes the cache and returns an empty content array with no output tokens billed. It is rejected with streaming, extended thinking, structured outputs, forced tool_choice, or inside a Message Batches request.
Step 6: Understand the rate limit benefit
Caching also raises your effective throughput. For most Claude models, only uncached input tokens count toward input tokens per minute (ITPM): input_tokens and cache_creation_input_tokens count, while cache_read_input_tokens does not. The rate limits page gives an example: with a 2,000,000 ITPM limit and an 80 percent cache hit rate, you could process 10,000,000 total input tokens per minute. Claude Haiku 3.5 is listed as an exception that also counts cache reads. This is one more reason to cache the long, shared part of agent prompts, as in Claude Tool Use in Python: Build a Simple Agent Loop Step by Step.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Both cache fields are 0 | Prompt below the model's minimum length | Cache more content or accept that this request is too short |
| Cache writes every request, no reads | Something before the breakpoint changes each time | Diff the serialised prefix between two requests; move volatile values after the breakpoint |
400 error on cache_control | Different TTL on the last block, or more than four breakpoints | Use one TTL on the last block and count breakpoints |
| Hits stop after a quiet period | The 5-minute TTL expired | Use the 1-hour TTL or warm the cache before traffic |
| Hits stop after a prompt change | Prefix no longer identical | Keep tools and system stable; change only the messages |
| Concurrent requests all write | No entry exists until the first response starts | Send the first request, then fan out |
Checklist
- The cached prefix is above the model's minimum length.
- Stable content comes first, volatile values come last.
- The breakpoint is on the last stable block, and you use at most four.
- You chose 5 minutes or 1 hour based on how often the prefix is reused.
- You log
cache_creation_input_tokensandcache_read_input_tokensand watch the hit rate. - You handle rate limits as described in Handling LLM API Rate Limits: Retry, Backoff and Queues in Python.
Comments
Questions and tips are welcome. Comments are checked by the EpiFive team before they appear; please do not share passwords, phone numbers or other private details.