AI agents

Comparing Prefix Caching Rules Across Three Providers

Antonio Evans9 min read

A clean side-by-side diagram of three stacked prompt blocks, each with a different way of marking the cached prefix: one block has explicit breakpoint flags at segment boundaries.
Key points

Key points

  1. 1Prefix caching is an exact prefix match, so any byte change before the cache breakpoint invalidates every token after it.
  2. 2The three providers differ on how you declare a breakpoint, how long cached entries survive, and how much prefix (or whether a breakpoint) is required before caching applies.
  3. 3Standardize on a stable-prefix-first prompt layout and a single internal function that emits cache markers, so a provider swap changes config, not prompt structure.
  4. 4Log cache-read and cache-write token counts from every response; without them you cannot tell a working cache from a silent miss.

The mechanism every provider shares

Prompt caching stores the model's key and value tensors for a prompt prefix instead of the text itself, so a later request that starts the same way skips the prefill computation for that prefix OpenAI's prompt caching guide. Attention is causal: the vectors for token 500 depend on tokens 1 through 499 and nothing later. Change token 12 and every vector from 12 onward is different, which is why only a prefix can be reused Firecrawl's caching write-up.

Three consequences follow, and they hold on all three providers:

  1. Matching is byte exact. Firecrawl's summary of the mechanics notes the match is keyed on the literal token sequence, so one changed character before the boundary breaks the hit Firecrawl.
  2. Only input tokens are discounted. Output is recomputed and billed in full, and Anthropic's docs state the response is identical to what you would get without caching Anthropic prompt caching docs.
  3. The discount is large enough that a miss is visible in the bill. Cache reads run at a fraction of base input price, which is why a harness that never hits the cache can cost several times what you modeled Minh Le Duc on cache invalidation.

One framing that helps before the comparison: prompt caching is not response caching and not semantic caching. The model still generates a fresh answer every time; only the processing of input tokens you already sent is reused Michael Hannecke's explainer.

Where the three providers diverge

The three providers below are Anthropic (Claude), OpenAI, and Claude served through Google's Gemini Enterprise Agent Platform, which is a useful third case because it runs the same models under a different operational wrapper.

How breakpoints are declared

Anthropic offers two modes. Automatic caching adds a single top-level cache_control field, and the system applies the breakpoint to the last cacheable block and moves it forward as the conversation grows. Explicit caching places cache_control on individual content blocks for fine-grained control Anthropic docs. The docs recommend automatic caching as the simplest start, particularly for multi-turn conversations.

OpenAI's model is different: caching is applied automatically on prompts that qualify, and you cannot and need not place a breakpoint OpenAI's announcement. The API caches the longest prefix previously computed, and the guide describes the cache as storing KV tensors rather than tokens OpenAI guide.

The portability rule: never hard-code cache_control at call sites. Put marker emission behind one function that takes the prompt parts and the provider name, and returns either markers or nothing.

How long the cache lives

Anthropic's default lifetime is 5 minutes, refreshed at no additional cost each time the cached content is used. A 1-hour tier exists at a higher write premium. Crucially, the lifetime is measured from the start of the request that writes or reads the entry, not from the end of its response, so a 4-minute streaming response leaves roughly 1 minute for the next request to arrive Anthropic docs. Technspire's analysis of the pricing mechanics reaches the same conclusion: long-streaming agent turns eat their own TTL Technspire.

OpenAI states caches are typically cleared after 5 to 10 minutes of inactivity and are always removed within one hour of last use OpenAI announcement.

Through Google's platform, the behavior follows Anthropic's documentation, with one operational addition worth knowing: caches are scoped to your Google Cloud project and cannot be used by other projects, and an administrator can disable explicit caching for a project, after which requests with caching enabled are rejected Google Cloud's Claude prompt caching page.

The portability rule: record a TTL assumption per deployment in configuration, and size your scheduling to it. If your job runs every 12 minutes, a 5-minute cache will miss on every run and you will pay the write premium forever.

Minimum prefix length before caching applies

OpenAI applies caching automatically on prompts longer than 1,024 tokens, caching the longest previously computed prefix starting at 1,024 tokens and increasing in 128-token increments OpenAI announcement.

Anthropic sets a per-model minimum, and it is not monotonic across generations. One implementation guide tabulates minimums ranging from 512 tokens on newer Opus and Fable models, 1,024 on Sonnet 5 and Sonnet 4.6, 2,048 on Opus 4.7, and 4,096 on Opus 4.6, Opus 4.5 and Haiku 4.5, and notes that a prefix under the minimum silently does not cache: you see a cache creation count of zero and keep paying full price Hidekazu Konishi's guide. Technspire's page repeats those per-model minimums Technspire.

The portability rule: assert the minimum in code. Before shipping, count the tokens of the stable prefix and compare against the smallest minimum among the models you route to, not just the model you tested on.

The comparison table

The table compiles the published rules. Read the "rule it implies" column as the thing to write into your own code.

DimensionAnthropic (direct)OpenAIClaude via Google CloudPortability rule
How you enableTop-level cache_control (automatic) or per-block markers (explicit) sourceAutomatic above the token floor, no marker sourceSame as Anthropic, plus project-level disable sourceEmit markers through one function with a provider switch
Default TTL5 minutes, refreshed free on each use; 1-hour tier at higher write cost sourceTypically 5 to 10 minutes idle, removed within 1 hour of last use sourceFollows Anthropic behavior; cache scoped to project sourceStore the TTL per deployment in config and schedule to it
Minimum lengthPer model, from 512 to 4,096 tokens depending on generation sourceAbove 1,024 tokens, in 128-token increments sourceAs Anthropic sourceCount prefix tokens in a test and assert against the smallest minimum
Where the breakpoint sitsOn the last block identical across requests sourceNot applicable, the longest prefix is cached sourceAs Anthropic sourceStable block first, volatile content last, always
What invalidation followsTools, then system, then messages; each level invalidates itself and all later levels sourceAny change inside the matched prefix reduces the cached portion sourceAs Anthropic sourceTreat tool definitions and system text as frozen per deploy
Hit reporting in the responseCache creation and cache read input token fields sourceA cached tokens value inside the usage field sourceAs Anthropic sourceNormalize both shapes into one internal metric

Where the breakpoint goes, and what breaks it

The best rule from Anthropic's own documentation, as quoted by a walkthrough of the docs: place the breakpoint on the last block that stays identical across requests. For a prompt with a static prefix and a varying suffix such as a timestamp, per-request context or the incoming message, that is the end of the prefix, not the varying block the breakpoint walkthrough.

The hash is cumulative. It covers everything up to and including the breakpoint, so editing any block at or before the mark produces a different hash next time. Invalidation follows a hierarchy: tools, then system, then messages, and a change at each level invalidates that level and all later levels breakpoint walkthrough. Practically: changing a tool definition loses everything; changing tool choice or adding an image affects only the message blocks.

This is the same failure the Claude Code team built around. An engineer on that team described prompt caching as the architectural constraint the whole product is built on, and the team declares incidents when hit rates drop. Adding an MCP tool, putting a timestamp in the system prompt, or switching models mid-session can each invalidate the cache and multiply the cost of that turn Claude Code caching analysis.

The most common silent mistake is a dynamic system prompt. A timestamp at position zero means every request writes a new cache entry and reads none, with no error and no warning, just cache creation tokens on every call and read tokens always zero breakpoint walkthrough. Minh Le Duc's cost model puts a number on it: a timestamp in the system prompt cost 7.8x on an 80-turn session, not because the timestamp is expensive but because it forfeits the discount on every turn Minh Le Duc.

A worked example with numbers

Take an agent that sends a 20,000-token stable prefix (tool definitions, system instructions, reference docs) on every call, with a variable user message after it. Assume a Sonnet-tier model at 1,024-token minimum and a 5-minute TTL with a 1.25x write premium and a 0.1x read rate, the multipliers Anthropic publishes Technspire.

Three scenarios over 100 requests, all arriving within the TTL window:

ScenarioEffective cost per request (in units of base input rate x 1,000 tokens)Notes
No caching20.020,000 tokens at full rate
Cache hit, steady traffic2.020,000 tokens at 0.1x
Cache miss on every call25.020,000 tokens at 1.25x write, never read

The miss case is the one teams do not plan for, and it is worse than no caching at all. The break-even is low: Technspire frames it as the 5-minute tier paying for itself after one cache read, because 1.25x write plus 0.1x read is 1.35x against 2x for two uncached passes Technspire.

Now change traffic. If requests arrive every 12 minutes, a 5-minute cache never survives, and every call is a write at 1.25x. Moving to the 1-hour tier at a 2x write still beats repeated 5-minute writes, and the read refreshes the lifetime at the read price Technspire. That is the decision rule in one line: compare your inter-request gap to the TTL before choosing a tier, then verify with the token counts in the response.

On pricing levels generally, published comparisons of the cross-provider economics report cache reads between 0.025x and 0.1x of base input, and note that a write pays for itself after one reuse at the 1.25x tier and two at the 1-hour tier Firecrawl. Check current rates against the provider's own pricing page before forecasting.

Standardizing prompt layout, markers and cost tracking

Four habits make a provider swap a configuration change.

Order content by stability. Tool definitions first, then system instructions, then reference material, then conversation history, then the live user message. Any change invalidates that block and everything after it, so dynamic data must live at the very end Digital Applied. The same source reports one team moving dynamic working memory out of the system prompt into a user message at the end, taking a cache hit rate from 7% to 84% Digital Applied.

Route markers through one function. Something like this, where the provider decides whether anything is emitted at all:

def build_messages(parts, provider, ttl_seconds):
    # parts: ordered list of {"role": ..., "text": ..., "stable": bool}
    blocks = [{"type": "text", "text": p["text"]} for p in parts]
    if provider == "anthropic":
        last_stable = max(i for i, p in enumerate(parts) if p["stable"])
        blocks[last_stable]["cache_control"] = {"type": "ephemeral"}
    # openai and other automatic providers: no marker needed
    return blocks

The function reads the stable flag rather than trusting the caller to put markers in the right place. That makes the breakpoint reproducible across call sites and reviewable in one diff.

Put TTL assumptions in configuration. A key per deployment (provider, model class, TTL tier, minimum prefix tokens) means changing providers edits a config file. It also lets you fail fast when a scheduled job's interval exceeds the TTL.

Normalize cache metrics from each response. Anthropic reports cache creation and cache read input tokens separately, and total prompt size is the sum of the three fields, which means input_tokens is only the uncached remainder Technspire. OpenAI reports a cached tokens value inside the usage details OpenAI announcement. Map both into one internal record: read tokens, write tokens, uncached input, model, and a request ID. Then alert on the ratio of read to total input per route, not on the raw bill, because the bill moves with traffic while the ratio moves with structure.

If you route across several model families and would rather not maintain a per-provider adapter for each one, an OpenAI-compatible gateway such as Quanta Inference lets you keep one key and one request shape while you decide which provider sits behind it.

A pre-ship checklist

Run this before you switch providers or ship a new prompt layout.

  • The stable prefix is contiguous and sits at the very start of the request.
  • No timestamps, request IDs, session state or user names appear before the breakpoint.
  • Token count of the stable prefix exceeds the smallest per-model minimum on every model you route to.
  • Cache markers are emitted by one function and covered by a unit test that asserts marker position.
  • TTL is set in configuration, and your request interval is shorter than it, or you use a longer tier.
  • Tool definitions are versioned and do not change between deploys without a deliberate cache reset.
  • Each response's cache read and cache write counts are logged and normalized into one metric.
  • A dashboard shows read-to-input ratio per route, with an alert threshold.
  • One test request runs twice in a row and asserts that the second reads from cache.

The last item is the cheapest test in the list and catches every silent failure described above. If the second call reports zero read tokens, something before the breakpoint changed, and no amount of prompt tuning will fix it.

FAQ

FAQ

Why does my cache never hit even though the prompt looks the same?

One byte before the breakpoint changed. The usual culprits are a timestamp or request ID in the system prompt, an unstable JSON serialization of tool definitions, a model or effort switch mid-session, or an idle gap longer than the TTL. The breakpoint walkthrough lists the hierarchy explicitly: tools, then system, then messages, and a change at each level invalidates that level and every level after it breakpoint walkthrough. Confirm with the response fields, where creation tokens appear on every call and read tokens stay at zero.

Do I need cache markers on every provider?

No. Anthropic supports both automatic caching with a single top-level field and explicit per-block markers, and its docs recommend the automatic form as the simplest start Anthropic docs. OpenAI applies caching automatically above its token floor with no integration change OpenAI announcement. That asymmetry is exactly why markers belong behind one internal function with a provider switch, so a request to a provider that needs nothing simply carries nothing.

Can switching providers change my bill without changing my prompts?

Yes, in three ways: the minimum prefix length can rise above your stable block, the default TTL can shorten so scheduled jobs always miss, and the write premium can differ. Anthropic's per-model minimums range from 512 to 4,096 tokens, so a prefix that caches on one model may silently fail on another Hidekazu Konishi's guide. A prefix under the minimum produces no error, just full-price input.

Is a cache miss worse than not caching at all?

On a write-premium provider, yes. A miss means you paid the write multiplier and got no read. With a 1.25x write and a 0.1x read, the 5-minute tier pays off after a single read, but a workload that never reads just pays 1.25x on every call Technspire. The fix is structural, not a toggle: repair the prefix or drop to no marker until the layout is stable.

Does caching change the model's output?

No. Anthropic's documentation states the response is identical to what you would get without caching, and the general mechanism explanation makes the same point: caching only affects processing of input tokens you already sent Anthropic docs. It reduces time to first token because prefill is skipped, but generation speed and output content are unchanged Michael Hannecke's explainer.

Sources

Sources

  1. Prompt caching | OpenAI API
  2. Prompt Caching: How It Works, What It Costs ...
  3. Prompt caching - Claude Platform Docs
  4. Five ways to invalidate your prompt cache | by Minh Le Duc
  5. Prompt Caching: What It Is, What It Is Not
  6. Prompt Caching in the API
  7. Anthropic Claude prompt caching pricing: write, read, TTL ...
  8. Prompt caching | Gemini Enterprise Agent Platform
  9. Anthropic Claude API Prompt Caching and Token ...
  10. How Prompt Caching Actually Works in Claude Code
  11. What Invalidates a Prompt Cache, Where the Breakpoint Goes ...
  12. Prompt Caching in 2026: Cut LLM Costs, Keep Quality
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles