Claude prompt caching cost: 90% off, or 25% more
Published · Updated · OhChimp Engineering

Prompt caching bills a repeated prompt prefix at 10% of the input rate, and the write that puts it there bills 125%, so the same cache_control line saves about 90% on a busy endpoint and costs 25% on a quiet one. The difference is how often you call, and nothing in the API response tells you which side of it you landed on.
Why a cache read bills a tenth
Prompt caching is an Anthropic API feature that stores a repeated prompt prefix, such as a system prompt, a block of tool definitions or a few-shot set, so a later request carrying that same prefix reuses the stored work instead of paying to process it again. The API turns your prompt into internal state before it generates a single token, and the cache holds that state. A request whose prefix matches an existing entry exactly skips the work and reads the entry, which is why a read prices well under raw input.
Anthropic publishes the discount as three multipliers on each model's base input price. A 5-minute cache write costs 1.25x, a 1-hour cache write costs 2x, and a cache read costs 0.1x.
In dollars per million tokens, for three current models:
| Model | Base input | 5m cache write | 1h cache write | Cache read |
|---|---|---|---|---|
| Claude Opus 5 | $5.00 | $6.25 | $10.00 | $0.50 |
| Claude Sonnet 5 | $2.00 | $2.50 | $4.00 | $0.20 |
| Claude Haiku 4.5 | $1.00 | $1.25 | $2.00 | $0.10 |
The write premium is what turns caching into a decision instead of a default. One write followed by R reads costs 1.25 + 0.1R units of the base input price, against R + 1 units for the same calls uncached. Solve for the crossover and you get R > 0.28, so the very first read pays the premium back. Switch to the 1-hour TTL and the write costs 2x, the crossover moves to R > 1.11, and you need two reads before the entry has earned its keep.
Take a 20,000-token prefix on Sonnet 5, roughly what a production endpoint carries once you count the system prompt, the tool definitions and a few-shot block. That prefix costs $0.040 per call uncached, $0.004 as a cache read, and $0.050 as a 5-minute write.
| Reads per write | Cached | Uncached | Saving |
|---|---|---|---|
| 0 | $0.050 | $0.040 | you pay 25% more |
| 1 | $0.054 | $0.080 | 32.5% |
| 3 | $0.062 | $0.160 | 61.3% |
| 9 | $0.086 | $0.400 | 78.5% |
| 39 | $0.206 | $1.600 | 87.1% |
The saving climbs toward 90% and never arrives, because the write never quite amortizes away.
The write nobody reads back
A 5-minute cache write that nothing ever reads back bills 25% more than leaving the prefix uncached. That is the top row of the table, and landing on it takes no mistake a code review would catch.
A cache entry lives 5 minutes by default. The clock starts at the beginning of the request that writes or reads the entry rather than at the end of its response, so generation time comes out of the window you have left. Anthropic's prompt caching documentation puts a number on it: a response that takes four minutes to stream leaves about one minute for the next request to arrive.
A scheduled job that runs every 10 minutes against a 5-minute entry never reads its own cache. Every run writes a fresh entry, that entry expires unread, and the next run writes it again. At 4,320 calls a month (one every 10 minutes, around the clock, across a 30-day month) with that 20,000-token prefix on Sonnet 5, the bill reads $216.00 against $172.80 with nothing cached. One line of configuration, $43.20 a month.
The 1-hour TTL exists for that cadence and carries a floor of its own. Its write costs 2x, so a single read leaves you 5% worse off than caching nothing, and the saving only begins at the second read.
Concurrency strands writes at the other end of the traffic range. An entry becomes available only once the first response carrying that prefix has begun, which Anthropic states in its cache limitations along with the remedy: wait for that first response before sending the rest. A fan-out that opens with twenty simultaneous calls against a cold prefix therefore buys twenty writes and no reads.
The quietest way to strand a write is the prompt itself. Cache matching runs over a prefix in a fixed order, tools then system then messages, and a change at any level invalidates that level and everything downstream of it. Drop a timestamp, a request id or a signed-in user's name near the front of the system prompt and every call writes an entry no later call can match. One variable byte that high in the prompt puts the whole workload on the 25% row rather than one slow cron job.
Length is the other silent failure. A prefix shorter than the model's minimum is not cached, the cache_control you set is ignored, and no error comes back.
| Model | Minimum cacheable prefix |
|---|---|
| Claude Opus 5 | 512 tokens |
| Claude Sonnet 5 | 1,024 tokens |
| Claude Haiku 4.5 | 4,096 tokens |
The minimum runs opposite to price: Opus 5 caches from 512 tokens, Sonnet 5 from 1,024, and Haiku 4.5, the cheapest of the three, only from 4,096. A 2,000-token system prompt therefore caches on Opus 5 and on Sonnet 5 and does precisely nothing on Haiku 4.5. A team that moves a workload down to Haiku to save money can lose its caching in the same change and never notice, because the invoice still goes down.
If you reach Claude through Bedrock rather than the Claude API, the caching question sits next to a different one: provisioned throughput bills whether you call it or not.
Find your cache misses by hand
Every Messages API response reports what actually happened, so one call answers the question for one endpoint.
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d @request.json | jq '.usage'
{
"input_tokens": 42,
"cache_creation_input_tokens": 20143,
"cache_read_input_tokens": 0,
"output_tokens": 218
}
Send the same request twice inside the TTL. On the second call cache_creation_input_tokens should drop to 0 and cache_read_input_tokens should carry the prefix. Both fields sitting at 0 on both calls means the prefix never met the model's minimum length.
One endpoint is a sample. The Admin API reports the same counters across every key in the organization, which is where a workload nobody remembers shipping turns up. It takes an Admin API key (sk-ant-admin...), a separate credential from the one your application authenticates with.
curl -sG https://api.anthropic.com/v1/organizations/usage_report/messages \
-H "x-api-key: $ANTHROPIC_ADMIN_KEY" \
-H "anthropic-version: 2023-06-01" \
--data-urlencode "starting_at=$(date -u -d '30 days ago' +%Y-%m-%dT00:00:00Z)" \
--data-urlencode "bucket_width=1d" \
--data-urlencode "group_by[]=model" \
--data-urlencode "limit=31" \
-o usage.json
On macOS the date flags differ: date -u -v-30d +%Y-%m-%dT00:00:00Z. A 1d bucket width caps at 31 buckets per page, and has_more with the next_page cursor carries you further back. Roll the buckets up per model and the three cases separate cleanly.
jq -r '
[.data[].results[]]
| group_by(.model)[]
| {
model: .[0].model,
uncached: (map(.uncached_input_tokens) | add),
writes: (map(.cache_creation.ephemeral_5m_input_tokens
+ .cache_creation.ephemeral_1h_input_tokens) | add),
reads: (map(.cache_read_input_tokens) | add)
}
| [.model, .uncached, .writes, .reads]
| @tsv
' usage.json | column -t
Read the three columns together rather than one at a time.
- Heavy
uncachedwithwritesandreadsboth at zero means caching never engaged. Either no breakpoint is set, or the prefix sits under the model's minimum. writesclimbing withreadsat or near zero means the breakpoints are set and nothing ever matches them. Those tokens billed at 1.25x or 2x, and this is the case that costs more than doing nothing.readswell abovewritesmeans caching is working, and the read-to-write ratio maps onto the table above: nine reads per write is about a 78% saving on that prefix.
Restructure the prompt, keep the words
The fix is ordering, and it usually changes no wording at all. Cache matching is prefix matching, so every stable byte has to sit ahead of every variable one: tool definitions first, then the system prompt, then any examples, then the user's actual input last. Mark the end of the stable region with a breakpoint.
{
"model": "claude-sonnet-5",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "You classify support tickets. <the long stable instructions>",
"cache_control": { "type": "ephemeral" }
}
],
"messages": [{ "role": "user", "content": "Ticket 8817: card declined on renewal." }]
}
Pick the TTL from the gap between calls rather than from how long the content feels like it should live. Under five minutes, the default is right. Between five minutes and an hour, buy the longer entry only if you will read it at least twice.
"cache_control": { "type": "ephemeral", "ttl": "1h" }
A request carries at most four breakpoints. For a conversation where the cacheable tail grows every turn, a single cache_control at the top level of the request body hands the placement to the API, which puts the breakpoint on the last cacheable block and moves it forward as the history extends.
Rolling back means deleting the cache_control field. The next request bills its prefix at the base input rate, any entry already written expires on its own schedule, and there is nothing to clean up. Caching changes what you are charged for a prefix and leaves the prompt, the model and the response identical, so the rollback moves your bill and nothing else.
A quick decision tree
graph TD
A[Repeated prompt prefix] --> B{Prefix past the model's minimum?}
B -- No --> C[Nothing caches: grow the stable block or check the model's floor]
B -- Yes --> D{Gap between calls}
D -- Under 5 minutes --> E[5m breakpoint: pays back on the first read]
D -- 5 to 60 minutes --> F{Three or more calls in the hour?}
F -- Yes --> G[1h breakpoint: pays back on the second read]
F -- No --> H[Leave it uncached: every write expires unread]
D -- Over an hour --> H
Common questions
Does prompt caching ever cost more than not caching?
Yes. A cache write bills 1.25x the base input rate on the 5-minute TTL and 2x on the 1-hour TTL, so an entry that expires before anything reads it is billed above the uncached price. A job running every 10 minutes against a 5-minute cache writes on every run and reads on none, which costs 25% more than the same job with no cache_control at all.
How many cache reads does it take to break even?
One, on the 5-minute TTL. The write costs 1.25x and a read costs 0.1x, so a write plus a read comes to 1.35x against the 2x you would pay for two uncached calls. The 1-hour TTL writes at 2x and needs two reads: at a single read it costs 2.1x against 2x, which is 5% worse than leaving the prefix uncached.
Why are my cache_creation and cache_read token counts both zero?
The prefix is shorter than the model's minimum cacheable length, so the breakpoint is ignored and no error is returned. The minimum is 512 tokens on Claude Opus 5, 1,024 on Claude Sonnet 5 and 4,096 on Claude Haiku 4.5, which means the same prompt can cache on one model and silently skip caching on a cheaper one.
Does a cache read extend the entry's lifetime?
Yes, and the refresh costs nothing. Each read restarts the TTL from the start of the request that read it. Generation time counts against that window, so a response that streams for four minutes leaves about one minute of a 5-minute entry for the next call to land in.
What invalidates a cached prefix?
Cache matching runs over tools, then system, then messages, and a change at one level invalidates that level and everything after it. Editing a tool definition therefore drops the system and message caches as well. Variable content early in the prompt, such as a timestamp or a request id, has the same effect on every single call.
Is the 1-hour cache worth its 2x write?
It is when the gap between calls sits between five minutes and an hour and you make at least three calls inside that hour. One write and two reads costs 2.2x against the 3x for three uncached calls. Below three calls an hour the write premium outruns what the reads give back.
Why do my parallel requests all write instead of reading?
A cache entry becomes available only after the first response carrying that prefix has begun, so calls fired simultaneously against a cold prefix each write their own entry rather than reading a shared one. Anthropic's documented remedy is to wait for the first response to start before sending the rest, which turns a fan-out of twenty writes into one write and nineteen reads.
Does prompt caching stack with the Batch API?
Yes. Anthropic documents the caching multipliers as stacking with other pricing modifiers, the 50% Batch API discount included, so a cache read inside a batch job prices at 0.1x of the discounted input rate.
Can I roll prompt caching back?
Yes, by removing the cache_control field. The next request bills its prefix at the base input rate and any live entry expires on its own. The prompt, the model and the response are unchanged, so the only thing a rollback moves is what you are billed.
How OhChimp approaches this
OhChimp reads your organization's usage report, prices each model's uncached input, cache reads and cache writes at that model's real rates, and ranks the models by projected monthly cost so the expensive one is first. Cache-capable models carrying heavy input volume with no cached reads come back as a plan with the prompt-ordering fix written out, a confidence score, a risk level and rollback steps. You are the one who applies it. The saving is priced from your usage report, and OhChimp cannot yet measure what reordered prompts save once they ship, so it stays an estimate. The Anthropic integration page covers the read-only Admin API key the connection uses.