·SDKs & Tooling
A 2026 deep dive on Claude API Prompt Caching — four-tier pricing, cache_control breakpoint strategy, 5-min vs 1-hour TTL trade-offs, stacking with Batch API, multimodal caching (image / PDF blocks), and the five most common failure modes (below-threshold input, breakpoint change, TTL expiry, model namespace mismatch, mis-placed cache_control).
Claude Prompt Caching Deep Dive: 10x Cheaper Claude API Calls (2026)
Claude API's Prompt Caching — launched in October 2024 and matured through 2025–2026 — is a key feature that drops the cost of repeated prefixes to 0.1× base price on cache reads. This guide, based on the official docs and the claude-cookbooks notebooks, covers: the four-tier pricing model, cache_control breakpoint strategy, 5-min vs 1-hour TTL trade-offs, combining with the Batch API, and the five most common failure modes in 2026.
TL;DR
- Repeated prefixes cost 0.1× base price on cache reads; cache writes cost 1.25× (5-min TTL) or 2× (1-hour TTL)
- Mark breakpoints via
cache_control: { type: "ephemeral" }— every token up to and including the breakpoint is cached- Minimum threshold: 1024 tokens for Sonnet 4.5+, 4096 for Opus 4.5+. Sub-threshold inputs are not cached
- TTL choice: 5-min (default, 1.25× write) / 1-hour (2× write) — 1-hour only wins on 5+ rounds or batch workloads
- Stack: Prompt Caching + Batch API = double discount (~60% total); but Batch has no streaming and a 24h turnaround
Four-tier pricing: from 1.0× to 0.1×
The 2025-11 spec splits every Claude API call's token cost into four tiers — understanding them is the only way to calculate ROI correctly:
| Tier | Multiplier | When it applies | |---|---|---| | base input | 1.0× | First cache write, or any cache miss | | cache write (5-min TTL) | 1.25× | Extra cost to write into the 5-min cache (first time) | | cache write (1-hour TTL) | 2.0× | Extra cost to write into the 1-hour cache | | cache read | 0.1× | Prefix tokens that hit the cache |
Intuition: cache writes cost 25–100% extra; cache reads cost 90% less afterwards. As long as the hit count is high enough, you win. Rough ROI formula:
hit rate = cache_read / (cache_read + cache_write)
net savings = (1.0x - hit_rate × 0.1x) - hit_rate × cache_write_multiplier × 0.9
Example: a 1000-token system prompt + 100-token user input, hit rate 90%, 5-min TTL:
no cache: 1000 × 1.0 = 1000 tokens
with cache: 1000 × 1.25 = 1250 (first) + 1000 × 0.1 = 100 (every subsequent call)
10 calls: 1250 + 9 × 100 = 2150
vs no cache: 10 × 1000 = 10000
savings: 78%
Rule of thumb: long prefix + high call frequency = must enable cache; short prefix (< 1024 tokens) = wastes money.
cache_control breakpoints: what exactly gets cached
cache_control is an optional field on every content block in the messages array (TypeScript SDK: { type: "content", content: [...], cache_control: { type: "ephemeral" } }). When set, every token from the start of messages up to and including the breakpoint is cached.
Breakpoint placement decides what gets cached. Two common layouts:
Layout 1: single breakpoint after system — cache the entire system prompt
const response = await client.messages.create({
model: "claude-sonnet-4-5",
system: [
{
type: "text",
text: LONG_SYSTEM_PROMPT, // 8000 tokens: few-shot examples, rules, docs
cache_control: { type: "ephemeral" }
}
],
messages: [{ role: "user", content: userInput }]
});
Layout 2: multiple breakpoints per section — independently cache sections (long system + long doc library)
system: [
{ type: "text", text: ROLE_INSTRUCTIONS, cache_control: { type: "ephemeral" } },
{ type: "text", text: FEW_SHOT_EXAMPLES, cache_control: { type: "ephemeral" } },
{ type: "text", text: REFERENCE_DOCS } // not cached — changes per request
]
Common pitfalls:
- Putting
cache_controlafter the last system block but before the first user message is a common anti-pattern — you want the breakpoint on the last block you want cached. - Multiple breakpoints stack their overhead (each section is a separate cache write) — using too many is counter-productive.
- Content before the breakpoint must be stable — any change invalidates the entire cache block.
5-min vs 1-hour TTL: how to choose
Anthropic offers two TTL options:
type: "ephemeral"(default, 5-min rolling): each cache hit resets TTL to now + 5mintype: "ephemeral-1h"(added 2025-Q3, 1-hour): resets to now + 1h
Decision rule:
| Scenario | TTL | Why | |---|---|---| | Single-turn interaction (chat UI) | 5-min (ephemeral) | User won't come back; cache idle after 5min | | Multi-Tic conversation (same session) | 5-min | Renewed within session; dies naturally on session end | | Async batch task | 5-min | Batch usually < 24h; 5-min window is enough | | RAG + high-frequency retrieval | 1-hour | Same query template reused; cache stays stable | | Long-running agent loop | 1-hour | Same plan/execute template across rounds |
Intuition: the cache write multiplier (1.25× vs 2×) isn't the deciding factor — hit rate is. 1-hour TTL only wins if the cache is reused at least 5+ times; less than that, even 5-min is overkill.
Stack with Batch API: double discount
Prompt Caching and Batch API stack — but the scenarios are different:
- Prompt Caching: real-time / near-stream calls, saves repeated-prefix cost
- Batch API: async batch (24h turnaround), all tokens 50% off
Together: long system prompt + batch async task = double discount ~60% total cost. Trade-offs:
- Batch API doesn't support streaming — must wait for all requests to finish
- Batch API rate limits: 100k requests or 256 MB total input / batch, 24h expiry, results downloadable within 29 days
- Batch API doesn't support
max_tokens: 0(used for cache pre-warming) — you have to wait for a real request to trigger the cache
Pattern: dry-run the sync API first to validate params, then submit to Batch — Batch will reuse any cache you've already warmed.
Failure modes: when cache won't hit
The 5 most common cache miss causes:
- Below minimum: Sonnet 4.5+ needs 1024 tokens; Opus 4.5+ needs 4096. Short inputs simply don't cache.
- Breakpoint changed: every request recomputes the hash of the entire cache block. Change one character and you invalidate the whole thing.
- TTL expired: 5 minutes without a hit and the cache clears. Next write is a fresh
cache_write. - Different model: Haiku's cache, Sonnet can't read — each model has its own cache namespace.
cache_controlplaced wrong: breakpoint on the wrong block, or in the wrong position — the section you wanted cached is left out.
Debugging:
- Look at
usage.cache_creation_input_tokensandusage.cache_read_input_tokensin the response — the former > 0 means a write, the latter > 0 means a hit. cache_read_input_tokens == 0+ high call frequency = cache misconfigured.- Monitor the ratio of
cache_creation_input_tokenstocache_read_input_tokens: ideal is 1:N (one write, N reads).
Prevention: in CI, add a cache hit-rate assertion — after every call, assert cache_read_input_tokens / total_input_tokens > 0.5 (rolling 5-call average); fail the build if it drops.
Multimodal caching: image / PDF blocks cache too
cache_control works on every content block type — a capability that stabilised in late 2025:
const response = await client.messages.create({
model: "claude-sonnet-4-5",
max_tokens: 1024,
system: [
{
type: "text",
text: "You are a document analysis assistant. Answer user questions about the attached files.",
cache_control: { type: "ephemeral" }
},
// image blocks also participate in caching
{
type: "image",
source: {
type: "base64",
media_type: "image/png",
data: BASE64_PNG_OF_LONG_PDF_PAGE // large image (e.g2MB+ PDF→PNG)
},
cache_control: { type: "ephemeral" }
}
],
messages: [{ role: "user", content: "What number is in section 5 of page 3 of the image?" }]
});
Field scenarios:
- Multi-PDF RAG: turn each PDF into an image block (up to 1568×1568 px) and add
cache_control. Hit rate is high when many rounds ask about the same set of PDFs. - Long-screenshot analysis: product bug screenshots (multiple), UI-review documents — repeated screenshots across many rounds hit cache.
- Vision + text mix: image as system background ("look at this reference image") reused across rounds.
Gotchas:
- One image block caps at 1568×1568 px or ~5MB base64 — anything larger is rejected.
- Image hash uses a different algorithm from text, but cache behaviour is identical: 5-min TTL,
cache_creation/cache_readbilled separately. - The 1.25× write multiplier applies to image blocks the same way it does to text.
Payback: in a RAG setup where each PDF→PNG is ~1MB base64, uncached every round burns ~6,000 input tokens; cached rounds burn ~600 (cache_read at 0.1×). 10 rounds = ~90% input savings.
Frequently asked questions
How much cheaper is cache read vs base input?
90% off — cache-read tokens cost 0.1× base. But cache writes cost extra — 1.25× for 5-min TTL, 2× for 1-hour. So "net savings" depends on hit rate: at 100% hit, 10 calls cost 1.25 + 9 × 0.1 = 2.15× single base — vs 10× without — 78% savings.
5-min or 1-hour TTL? Which is default?
5-min (default type: "ephemeral") — enough for most scenarios. 1-hour wins only for long-running batch / high-frequency RAG / multi-round agent loops, because its cache write multiplier is 2× instead of 1.25×. Rule of thumb: try 5-min first; if hit rate stays under 70%, switch to 1-hour.
Can Prompt Caching work with extended thinking?
Yes, with caveats. The thinking block also gets cached — if you trigger extended thinking via the system (with budget_tokens), the thinking content enters the cache. But changing budget_tokens invalidates the cache block (the cache key includes thinking parameters). Practical advice: keep thinking parameters stable, or cache the part of the prompt that excludes thinking.
How do I verify cache is actually working?
Check the response's usage block for three fields:
cache_creation_input_tokens(> 0 = just wrote)cache_read_input_tokens(> 0 = hit)input_tokens(uncached remainder)
First call: cache_creation=1024, cache_read=0, input=N.
Subsequent hits: cache_creation=0, cache_read=1024, input=N.
Debugging key: if you see cache_creation repeatedly > 0 and cache_read stays at 0 — your cache config is wrong.
Can image or PDF blocks also be cached?
Yes. cache_control works on every content block type (text / image / tool_use / tool_result) — a single image block caps at ~1568×1568 px or ~5MB base64. Field scenarios: multi-PDF RAG (each PDF→image block with cache_control), long-screenshot analysis, vision + text mixed prompts. Payback: in a 10-round dialog, input tokens drop roughly 90% (every round from ~6,000 to ~600).
How do I debug a cache_control that isn't working?
Check these five in order: (1) breakpoint position — must be on the last block you want cached, not in front of the user message; (2) threshold — Sonnet 4.5+ needs 1,024+ tokens to cache; (3) TTL — 5 minutes without a hit and the cache clears; (4) model match — every model has its own cache namespace, no cross-model sharing; (5) content stability — any byte change before the breakpoint invalidates the whole cache block. Debug start: check whether usage.cache_creation_input_tokens == 0 (never wrote at all) or cache_read_input_tokens == 0 (wrote but never hit) — the former means configuration, the latter means breakpoint placement.
Official references
- Anthropic — Prompt Caching official documentation
- Anthropic — Batch Processing official documentation (stacks with caching)
- Anthropic — Models & Pricing (cache prices per model)
- Claude Cookbooks — Prompt Caching notebooks
- Anthropic Engineering Blog — Prompt Caching announcement (October 2024)
- Anthropic Engineering Blog — 1-hour cache announcement (2025-Q3)
- Claude API errors reference (cache_creation_error, etc.)
- Claude Agent SDK — Prompt Caching integration example
This guide is current as of August 2026 pricing and caching mechanics. Prices are governed by the official Pricing page; review your cache hit-rate metric every quarter.