Here is a cost problem almost every AI app has and almost nobody notices at first: you send the model the same 8,000-token system prompt — or the same retrieved document, or the same list of 30 tool definitions — on every single request, and you pay full input price for it every single time. At scale, that repeated prefix can be the majority of your bill.

Prompt caching fixes it. The idea is simple: tell the API which part of your request is stable, and it caches that prefix. The first request pays a small write premium; every request after that reads the cached prefix at roughly one-tenth the normal input price. This is the single highest-leverage cost change most Claude apps can make, and it's about four lines of code. (It's one of several levers worth knowing — see our roundup of AI cost-control tools for founders for the rest.)

Value up front: if 70% of your average request is a fixed prefix and you're serving repeated traffic, prompt caching cuts your input cost on that portion by ~90%. Here's how to turn it on, the pricing math, and the one mistake that silently disables it.

What gets cached, and the one rule that governs everything#

Caching is a prefix match. The API renders your request in a fixed order — toolssystemmessages — and caches from the start up to the point you mark. The rule that follows from this, and that everything else in this post is a consequence of:

Any byte change anywhere before the cache point invalidates everything after it.

So the stable stuff — your frozen system prompt, your deterministic tool list, the document you're answering questions about — goes first. The volatile stuff — the user's actual question, a timestamp, a request ID — goes last, after the cache point.

Step 1 — Turn it on (the simplest form)#

If you don't need fine-grained control, the easiest option is a single top-level cache_control on the request. It automatically caches the last cacheable block:

import anthropic

client = anthropic.Anthropic()

BIG_SYSTEM_PROMPT = open("system_prompt.md").read()  # e.g. 8K tokens, unchanging

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    cache_control={"type": "ephemeral"},   # <-- the whole change
    system=BIG_SYSTEM_PROMPT,
    messages=[{"role": "user", "content": "Summarize the key risks in this deal."}],
)

That's it. First call writes the cache; subsequent calls within the TTL read it.

Step 2 — Or place the breakpoint yourself#

When you want to cache a specific block — say a large document you'll ask many questions about, while the questions vary — put cache_control directly on that block:

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    system=[
        {"type": "text", "text": "You are a contract analyst."},
        {
            "type": "text",
            "text": LARGE_DOCUMENT,               # the stable, expensive part
            "cache_control": {"type": "ephemeral"},  # cache up to here
        },
    ],
    messages=[{"role": "user", "content": USER_QUESTION}],  # varies — after the cache point
)

You can place up to four cache breakpoints per request (useful for tools + system + a retrieved doc as separate tiers). By default the cache lives 5 minutes, and every read resets that clock — so a busy endpoint effectively keeps it warm for free. Need it to survive longer gaps? Ask for a one-hour TTL:

"cache_control": {"type": "ephemeral", "ttl": "1h"}

Step 3 — Do the pricing math so you know it pays off#

The economics (input side, per the July 2026 pricing):

So for the 5-minute cache: the first request pays 1.25×, and every subsequent request pays 0.1× instead of 1×. You break even on the second request and print money after that. Concretely, on Claude Opus 4.8 (input $5.00 / MTok), a cached 8K-token prefix costs about $0.04 to write once, then about $0.004 per read — versus $0.04 every time uncached. Ten requests: ~$0.08 cached vs ~$0.40 uncached.

Break-even is two requests for the 5-minute cache, three for the 1-hour cache. If your prefix genuinely changes every request, don't cache — there's no reusable prefix to hit.

One caveat: the prefix has to clear a minimum size to cache at all — 4,096 tokens on Opus 4.8 and Haiku 4.5, 2,048 on Sonnet 5. Below that, the marker is silently ignored (no error, just no cache).

Step 4 — Verify it actually worked#

This is the step people skip, and it's the one that matters. Read the usage block on the response:

print(response.usage.cache_creation_input_tokens)  # tokens written this request (~1.25x)
print(response.usage.cache_read_input_tokens)      # tokens served from cache (~0.1x)
print(response.usage.input_tokens)                 # uncached tokens (full price)

On the first request you should see cache_creation_input_tokens populated. On the second identical request, you want cache_read_input_tokens to jump and input_tokens to drop. If cache_read_input_tokens stays at zero across repeated requests, caching is silently off — and it's almost always one of these:

The fix is always the same: move the volatile thing after the last cache point, make its serialization deterministic, or delete it if it isn't load-bearing.

Takeaway#

Prompt caching is the rare optimization that is both trivial to add and enormous in effect: mark your stable prefix with cache_control: {type: "ephemeral"}, keep anything that changes at the very end of the request, and confirm cache_read_input_tokens is climbing. Do that and the biggest repeated line item in your inference bill drops by about 90% — for four lines of code and ten minutes of care about byte-for-byte prefix stability.

Sources: Claude prompt caching docs · Claude pricing · Claude models overview. Pricing and cache-minimum figures current as of July 2026.