ClaudeMap

·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_control after 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 + 5min
  • type: "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:

  1. Below minimum: Sonnet 4.5+ needs 1024 tokens; Opus 4.5+ needs 4096. Short inputs simply don't cache.
  2. Breakpoint changed: every request recomputes the hash of the entire cache block. Change one character and you invalidate the whole thing.
  3. TTL expired: 5 minutes without a hit and the cache clears. Next write is a fresh cache_write.
  4. Different model: Haiku's cache, Sonnet can't read — each model has its own cache namespace.
  5. cache_control placed 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_tokens and usage.cache_read_input_tokens in 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_tokens to cache_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_read billed 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

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.