Skip to content

Browse catalog

Search catalog

[READY] Type a title, tag, or description.

Optimization

Prompt cache floors: 512 on Opus 5, 4,096 on Haiku 4.5

AUTHOR
Bartłomiej Krupa
PUBLISHED
2026.07.29
UPDATED
2026.07.29
READ_TIME
7 min

Anthropic’s minimum cacheable prefix is model-dependent, and the ordering is the opposite of the obvious guess: the newest and most expensive models have the lowest floor. A prefix below the floor is not cached, no error is raised, and cache_creation_input_tokens stays at 0.

Minimum prefixModels
512 tokensOpus 5, Fable 5, Mythos 5
1,024 tokensOpus 4.8, Sonnet 5, Sonnet 4.6, Sonnet 4.5, Opus 4.1, Opus 4, Sonnet 4
2,048 tokensOpus 4.7, Mythos Preview, Haiku 3.5
4,096 tokensOpus 4.6, Opus 4.5, Haiku 4.5

These floors apply on every platform where the model is available. The old Amazon Bedrock override for Fable 5 was removed and no per-platform exception remains.

The routing trap

The non-monotonic ordering has one practical consequence worth more than the table itself.

A 3,000-token policy prefix caches on Opus 5 and silently never caches on Haiku 4.5. So the moment you do the sensible thing and fan high-volume work out to the cheap tier, that tier starts paying full input price on every call. The cost model you validated on the expensive model does not transfer down.

Check the floor for the model you route to, not the one you developed against. If you are tiering work across models, this belongs in the same review as the price table in Stop paying full price for repeat LLM calls.

Opus 5 moved the other way: it halved the Opus 4.8 floor from 1,024 to 512, so prompts previously too short to cache now create entries with no code change. Worth re-checking anything you wrote off as uncacheable.

Verify, don’t assume

Three fields in usage tell you what actually happened:

FieldMeaning
cache_creation_input_tokensWritten to cache this request (paid the write premium)
cache_read_input_tokensServed from cache this request (paid ~0.1x)
input_tokensProcessed at full price - the uncached remainder only

Total prompt size is input_tokens + cache_creation_input_tokens + cache_read_input_tokens. That last point catches people out: if a long-running agent reports 4,000 input_tokens, the rest was served from cache. Check the sum, not the single field.

The one-line diagnosis: if cache_read_input_tokens is 0 across repeated identical requests, either the prefix is changing or it is under the floor. Both are silent.

u = client.messages.create(**build_request()).usage
print(u.cache_creation_input_tokens, u.cache_read_input_tokens, u.input_tokens)
# call 1: write>0, read=0    -> healthy, cache written
# call 2: write=0, read>0    -> healthy, cache read
# call 2: write>0, read=0    -> prefix changing every call
# both 0 across calls        -> prefix is under the model's floor

To tell “changing” from “too short”, build the request twice and diff it - the byte that moved is rarely the suspected one. Full procedure in Don’t break the prompt cache; the one-line rule is cache-stable prefix.

Breakpoints are a budget of four

Maximum 4 cache_control breakpoints per request, counted across tools + system + messages combined. Top-level automatic caching consumes one slot.

Exceeding the limit returns a 400, which is the good outcome. The bad outcome is an agent loop that appends a breakpoint per turn as history grows, exhausts the budget mid-session, and starts rewriting the prefix instead of reading it.

Render order is tools -> system -> messages, and caching matches everything up to and including a marked block. So spend the budget from the front: one breakpoint after tool schemas, one after the system prompt, and give a rolling message window whatever remains.

system=[{
    "type": "text",
    "text": SYSTEM_PROMPT,
    "cache_control": {"type": "ephemeral"},           # 5-minute TTL (default)
    # "cache_control": {"type": "ephemeral", "ttl": "1h"},
}]

What invalidates what

Not every parameter change costs you the whole cache. There are three tiers, and a change only invalidates its own tier and below.

ChangeTools cacheSystem cacheMessages cache
Tool definitions added, removed, reorderedlostlostlost
Model switchlostlostlost
System prompt contentkeptlostlost
tool_choice, images, thinking on/offkeptkeptlost
Message contentkeptkeptlost

The useful read: you can flip tool_choice or toggle thinking per request without losing the tools-and-system cache. Only tool-definition and model changes force a full rebuild.

Two of those rows have an escape hatch, and they are gated separately:

  • System prompt content - append a {"role": "system", "content": "..."} message to messages instead of editing top-level system. Available today with no beta header on Opus 5, Opus 4.8, Fable 5, and Mythos 5. Not on Sonnet 5, which returns a 400.
  • Tool definitions - tool_addition / tool_removal blocks, Opus 5 onward behind the mid-conversation-tool-changes-2026-07-01 beta. The tool must already be declared with defer_loading: true.

Model switching has no escape hatch: caches are model-scoped. Keep the main loop on one model and push cheaper sub-tasks to a subagent.

Two silent failures that are not the floor

The 20-block lookback. Each breakpoint walks back at most 20 content blocks looking for a prior cache entry. A single turn that appends more than 20 blocks - routine in an agent loop with many tool-use and tool-result pairs - pushes the previous entry out of range, and the next request silently misses. Fix: place an intermediate breakpoint roughly every 15 blocks in long turns.

Concurrent requests all pay. A cache entry becomes readable only once the first response begins streaming. Fire N identical-prefix requests in parallel and every one of them pays full price, because none can read what the others are still writing. For fan-out, send one request, wait for its first streamed token, then release the rest.

Economics, and when caching is a loss

Cache reads cost ~0.1x base input. Writes cost 1.25x for the 5-minute TTL and 2x for the 1-hour TTL, which sets different break-even points:

TTLWrite costBreak-even
5 minutes1.25x2 requests (1.25 + 0.1 = 1.35x vs 2x uncached)
1 hour2x3 requests (2 + 0.2 = 2.2x vs 3x uncached)

So caching a prefix you call exactly once is a pure loss: you pay the write premium and never read it. The 1-hour TTL keeps entries alive across gaps in bursty traffic, but the doubled write means it needs more reads to pay for itself.

Pre-warming. To remove the cold-write latency from the first real request, send a max_tokens: 0 request at startup. It runs prefill, writes the cache, returns immediately with empty content, and bills no output tokens. Put cache_control on the last block shared with the real request - the system prompt or tool schemas - never on the placeholder user message. It is rejected with stream: true, with thinking explicitly enabled, with output_config.format, with a forced tool_choice, and inside a Batches request.

Only pre-warm when first-request latency is user-visible and there is a quiet moment before traffic. If requests already arrive more often than the TTL, they keep the cache warm themselves and a separate warm call is pure extra write.

Next move

Look up the floor for whatever model your highest-volume endpoint routes to, then log cache_read_input_tokens on it for a day. If it reads 0, you now have two candidate causes and a way to tell them apart. The placement discipline is in Don’t break the prompt cache, the output side of the bill is in Trim output, not the cache, and the full lever map is on the Optimization hub.

FAQ

What is the minimum prompt length for Anthropic prompt caching?
It depends on the model and the order is not intuitive: 512 tokens on Claude Opus 5 and Fable 5, 1,024 on Opus 4.8 and Sonnet 5, 2,048 on Opus 4.7, and 4,096 on Opus 4.6, Opus 4.5, and Haiku 4.5. A prefix under the model's floor is not cached and no error is raised - `cache_creation_input_tokens` simply stays at 0. Opus 5 halved the Opus 4.8 floor, so prompts previously too short to cache now cache with no code change.
Why does my prompt cache work on one Claude model but not another?
Almost always the per-model minimum. The floor is not monotonic across tiers or releases, so a 3,000-token prefix caches on Opus 5 (512-token floor) and silently never caches on Haiku 4.5 (4,096-token floor). This bites hardest right after routing bulk work to a cheaper tier to save money: that tier then pays full input price on every call. Check the floor for the model you route to, not the one you developed against.
How many cache_control breakpoints can one request have?
Four, counted across `tools` plus `system` plus `messages` combined, and top-level automatic caching consumes one of the slots. Exceeding the limit fails the request with a 400. The quieter failure is an agent loop that appends a breakpoint per turn as history grows and exhausts the budget mid-session, which rewrites the prefix instead of reading it.