Claude API

Prompt caching on the Claude API: up to 90% off repeated input

TL;DR

Prompt caching stores your repeated prompt prefix; later reads cost about 10% of input price and don't count toward ITPM. Put static content first, place the breakpoint after the last static block, and watch cache_read_input_tokens.

Your chatbot has a 3,000-token system prompt, 2,000 tokens of tool definitions and 20,000 tokens of product documentation. Each user question is a few dozen tokens, but you pay for all 25,000 tokens in front of it on every request. Claude API's prompt caching solves exactly this: the repeated beginning of the prompt is stored, and later requests pay only about 10% of the input price for that part (even less on some newer models). This post covers how to enable it, how it's priced and the mistakes that make the cache "never hit".

Two ways to enable it

Automatic: add cache_control at the top level of the request; the system places the cache point on the last block and moves it forward as the conversation grows. Good for multi-turn chat.

{
  "model": "claude-sonnet-5-5",
  "max_tokens": 1024,
  "cache_control": {"type": "ephemeral"},
  "system": "You are a customer support assistant...",
  "messages": [ ... ]
}

Manual (explicit breakpoints): put cache_control on individual blocks for precise control. Good when parts change at different rates.

"system": [
  {
    "type": "text",
    "text": "...long system prompt + product docs...",
    "cache_control": {"type": "ephemeral"}
  }
]

Core rules

  • Prefix order: tools → system → messages. The cache covers everything before, including the block with cache_control.
  • At most 4 breakpoints per request (automatic caching takes one slot).
  • Minimum length: prompts shorter than the model's threshold (512 to 4,096 tokens depending on the model) are not cached, and there's no error.
  • 100% match: a single different character before the breakpoint is a miss.

Pricing and lifetime

TypeMultiplier vs base input priceNotes
Cache write, 5-minute TTL (default)1.25×TTL refreshes for free on each use
Cache write, 1-hour TTL2×"ttl": "1h", good for sparse traffic
Cache read0.1× (default)Lower still on some newer models such as Opus 5.5, Sonnet 5.5

Quick maths: writing once costs 25% extra, but a single re-read already breaks even. Cache multipliers stack with Batch API discounts. Beyond price, on most models cache-read tokens don't count toward the ITPM rate limit, so effective throughput rises significantly.

What breaks the cache?

ChangeWhat is lost
Tool definitions (name, description, parameters)Everything
System prompt; toggling web search, citationsSystem + messages
tool_choice, adding/removing imagesMessages
Thinking parameters, request-level effortMessages (more on some models)

The classic mistake: a cache that never hits

  • Breakpoint on changing content: for example a block with a timestamp "Today is 10:32:15" or the user's message. The hash never matches: you pay the 1.25× write every time and never read. Put the breakpoint on the last static block and move dynamic parts after it.
  • Unstable JSON key order: some languages (Swift, Go) may shuffle key order in tool_use input, causing misses.
  • Parallel requests too early: the cache is only available after the first response starts. Fire 50 concurrent requests at once and none benefit; wait for the first.
  • Too many blocks added in one turn: the system only looks back up to 20 blocks to find an earlier entry. Add a breakpoint nearby if one turn produces many blocks.

Checking the response

"usage": {
  "input_tokens": 50,                  // after the last breakpoint, uncached
  "cache_creation_input_tokens": 0,    // just written to cache
  "cache_read_input_tokens": 25000,    // read from cache
  "output_tokens": 310
}

Total input = cache_read + cache_creation + input_tokens. If both cache fields are always 0, the prompt is below the threshold or the breakpoint is in the wrong place.

How to apply it

  • Dev: Order the prompt by stability: tools → system → documents → history → new question. Log the cache_read/total input ratio per request.
  • Tech Lead: Ban timestamps and request IDs in the system prompt. Keep thinking/effort parameters fixed within a conversation.
  • PM: For a chatbot with fixed documentation, caching is often the biggest cost cut that doesn't require changing models. Put "cache hit rate" on the cost dashboard.

Sources & references

  1. Prompt caching — Claude Docs
  2. Rate limits — Cache-aware ITPM — Claude Docs