Prompt caching

Claude API · Advanced · 13 min

Caching long system prompts, documents and tool lists is the single biggest saving for chat and agent apps.

Many requests start with the same long text: a big system prompt, a manual, a tool list, or the earlier part of a chat. Prompt caching stores the processed form of that beginning (the prefix) for a short time, so the next request that starts the same way skips the work. Cache reads cost a small fraction of normal input tokens and cut response time.

You turn it on with cache_control={"type": "ephemeral"}:

  • At the top level of the request (automatic caching): the API places the cache point on the last cacheable block and moves it forward as a chat grows. The easy choice for conversations.
  • On individual content blocks (explicit breakpoints), up to four per request, for fine control.

The prefix is built in a fixed order: tools, then system, then messages. A change anywhere invalidates the cache from that point on, so put stable content first and changing content last. Even a timestamp at the top of the system prompt ruins caching.

The cache lives 5 minutes by default, refreshed every time it is used; "ttl": "1h" keeps it an hour at a higher write price. Writing to the cache costs a bit more than normal input; reading is much cheaper. Prompts below a minimum length (hundreds to a few thousand tokens, depending on the model) are simply not cached.

Check usage: cache_creation_input_tokens (written now), cache_read_input_tokens (reused) and input_tokens (after the cache point). If both cache fields are 0, nothing was cached.

Example

import anthropic

client = anthropic.Anthropic()
MANUAL = open("product_manual.txt").read()      # long, never changes

def ask(question: str):
    return client.messages.create(
        model="claude-opus-5-5",
        max_tokens=500,
        system=[
            {"type": "text", "text": "Answer using only this manual."},
            {"type": "text", "text": MANUAL,
             "cache_control": {"type": "ephemeral"}},   # cache up to here
        ],
        messages=[{"role": "user", "content": question}],
    )

u1 = ask("How do I reset it?").usage
u2 = ask("What does the red light mean?").usage
print(u1.cache_creation_input_tokens, u2.cache_read_input_tokens)
# e.g. 42000 42000  -> second call read the manual from cache

Remember

  • cache_control marks the end of a reusable prefix (tools -> system -> messages)
  • Stable content first; any change before the breakpoint misses the cache
  • Verify with cache_creation_input_tokens / cache_read_input_tokens

Watch out for

  • Putting a timestamp or user name at the start of the system prompt, which changes the prefix every call.

Check yourself

  1. Both cache usage fields are 0 on every call. What is a likely cause?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: platform.claude.com/docs/en/build-with-claude/prompt-caching