Skip to content
HUIAHUB

GuideModels & inference

Prompt caching with the OpenAI, Claude and Gemini APIs: what is cached and what breaks it

Compare prompt caching API rules for OpenAI, Claude and Gemini, order prompts so the cache hits, avoid silent misses and measure savings from usage fields.

Edited by Published 8 min read8 sources

A prompt caching API reuses the work a model already did on the unchanged start of your prompt, so repeated system prompts, tool definitions and documents cost less and start faster. OpenAI and Gemini cache automatically, Claude caches when you add cache_control, and all three need the cached part to be byte-for-byte identical and above a minimum length. Each provider reports hits in its usage fields, which is the only reliable way to know the cache worked.

What prompt caching does and when it pays off

A model turns input tokens into internal key-value states before it writes anything. Prompt caching saves those states for a prefix, the unchanged tokens at the start of a request. When the next request starts with the same prefix, the provider reads the saved states and only processes the new part.

Caching pays off when a large, stable block sits in front of many short, varying requests. Long system prompts, tool definitions, few-shot examples, reference documents and growing chat histories all fit. A short prompt, or one whose start changes each time, gains nothing.

OpenAI's guide gives the arithmetic for its newer models. A cache write costs 1.25× the normal input rate and a read 0.1×, so writing a prefix once and reusing it once costs 1.35× its ordinary input cost, against 2× without caching. Across ten requests, one write and nine reads cost 2.15× against 10×.

The three providers side by side

The figures below come from the OpenAI prompt caching guide (opens in a new tab), the Claude prompt caching docs (opens in a new tab) and the Gemini context caching docs (opens in a new tab), checked on October 12, 2026. Prices change, so confirm them on each pricing page, such as the Gemini API pricing page (opens in a new tab), before you budget.

OpenAI (GPT-5.6 and later)ClaudeGemini
How it turns onOn by default. Implicit mode places a breakpoint at the latest eligible message; explicit mode uses prompt_cache_breakpointTop-level cache_control (automatic) or cache_control on up to 4 blocks (explicit)Implicit caching on by default for Gemini 2.5 and newer; explicit caches created with caches.create
Minimum prefix1,024 visible input tokens512 tokens on Claude Opus 5.5, Sonnet 5.5 and Haiku 5.5; 1,024 on Claude Sonnet 5 and Sonnet 4.6; 4,096 on Claude Opus 4.6 and Haiku 4.54,096 on Gemini 3.8 Flash, 3.6 Flash and 3.1 Pro Preview; 2,048 on Gemini 2.5 Flash and 2.5 Pro
LifetimeAt least 30 minutes after the latest write or reuse (ttl value 30m)5 minutes by default, refreshed free on each hit; 1 hour optionalImplicit: not stated. Explicit: TTL defaults to 1 hour, no minimum or maximum
Cache write price1.25× the uncached input rate1.25× base input for 5 minutes, 2× for 1 hourNo separate write rate listed; explicit caches pay hourly storage, $0.50 per 1M tokens per hour on Gemini 3.8 Flash through December 31, 2026
Cache read price0.1× the uncached input rate (0.05× on GPT-6.1 Sol)0.1× base input on most models; 0.05× on Claude Opus 5.5 and Sonnet 5.5$0.075 per 1M tokens against $0.75 input on Gemini 3.8 Flash through December 31, 2026
Saving on a hitRead rate applies to every matched tokenRead rate applies to every matched tokenImplicit: no guarantee. Explicit: guaranteed
Hit reported inusage.input_tokens_details.cached_tokens and cache_write_tokenscache_read_input_tokens and cache_creation_input_tokensusage_metadata (generateContent) or usage.total_cached_tokens (Interactions API)

Older OpenAI models behave differently. GPT-5.5 and earlier only cache implicitly and charge no cache-write fee. Their lifetime is set with prompt_cache_retention: in_memory (about 5 to 10 minutes of inactivity, up to one hour) or 24h, depending on the model.

OpenAI: automatic caching and how to check for a hit

OpenAI caches the full rendered context, including developer messages, tool definitions and conversation history with text, images and documents. You do not opt in. On GPT-5.6 and later you can choose implicit or explicit-only mode with prompt_cache_options.mode.

Explicit-only mode is useful when a static block is followed by content that changes on every call. Mark the end of the static block, and everything after it is billed at the plain input rate without a write charge:

{
  "model": "gpt-6.1-sol",
  "prompt_cache_options": { "mode": "explicit" },
  "input": [
    {
      "role": "developer",
      "content": [{
        "type": "input_text",
        "text": "Stable instructions and reference material...",
        "prompt_cache_breakpoint": { "mode": "explicit" }
      }]
    },
    { "role": "user", "content": "Today's question..." }
  ]
}

Each request can create up to four cache writes. Top-level instructions cannot hold a breakpoint, so put reusable instructions in an input_text block inside a developer message. To check a hit, read usage.input_tokens_details.cached_tokens on the response.

Claude: cache breakpoints and lifetimes

Claude caches the prefix in a fixed order: tools, then system, then messages. The quickest start is a single top-level "cache_control": {"type": "ephemeral"}, which moves the breakpoint forward to the last cacheable block as a conversation grows. For a prompt with a stable head and a changing tail, place the breakpoint yourself on the last block that stays the same:

import anthropic

client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-opus-5-5",
    max_tokens=1024,
    system=[{
        "type": "text",
        "text": LONG_STABLE_INSTRUCTIONS,
        "cache_control": {"type": "ephemeral"},
    }],
    messages=[{"role": "user", "content": question}],
)
print(response.usage.cache_read_input_tokens, response.usage.cache_creation_input_tokens)

Two lifetime details catch people out. The 5-minute clock starts when the request that writes or reads the entry starts, so a response that streams for 4 minutes leaves about 1 minute for the follow-up. For prompts reused less often than every 5 minutes but more often than hourly, the docs point to "ttl": "1h", priced at 2× base input for the write.

Reads look backward from each breakpoint for at most 20 blocks. A conversation that adds 20 or more blocks between cache writes loses its hit unless you add a second breakpoint closer to the earlier write.

Gemini: implicit and explicit caching

Gemini's implicit caching (opens in a new tab) is on by default for Gemini 2.5 and newer models, and Google passes on the saving automatically when a request hits. The docs offer two tips: put large, common content at the start of the prompt, and send requests with a similar prefix within a short time. Implicit hits carry no cost-saving guarantee.

Explicit caching works differently. You upload content once as a named cache object with a TTL, then reference it by name:

from google import genai
from google.genai import types

client = genai.Client()
cache = client.caches.create(
    model="models/gemini-3.8-flash",
    config=types.CreateCachedContentConfig(
        system_instruction="You answer questions about the attached manual.",
        contents=[manual_file],
        ttl="3600s",
    ),
)
response = client.models.generate_content(
    model="models/gemini-3.8-flash",
    contents="Which torque setting applies to part 14?",
    config=types.GenerateContentConfig(cached_content=cache.name),
)
print(response.usage_metadata)

Explicit caching is in Beta under v1beta and only works through the generateContent API. The Interactions API supports implicit caching alone. After creation you can change only the ttl or expire_time of a cache, and you pay for storage for as long as it lives.

How to order a prompt so the stable part comes first

All three providers match from the first token forward, so one changed token early in the prompt throws away everything after it. Order each request from least to most volatile:

  1. Tool definitions, in a fixed order with fixed schemas.
  2. System or developer instructions without dates, user names or request IDs.
  3. Reference documents and few-shot examples.
  4. Conversation history, appended and never rewritten.
  5. Per-request content: the timestamp, the user's profile, the new question.

OpenAI's guide adds a tools rule: to stop the model calling a tool, set tool_choice to "none" or restrict calls with allowed_tools instead of deleting the definition. For a new instruction partway through a conversation, Claude's docs describe appending a {"role": "system"} message to messages on newer models, which leaves the cached system field untouched.

Mistakes that silently miss the cache

None of these return an error. The request succeeds, and you pay full price.

ChangeWhat happens
Prefix below the model's minimumNot cached. Claude reports 0 in both cache fields
Timestamp or user ID near the topThe prefix differs on every request, so no request reads an earlier entry
Claude breakpoint on the block that changes each requestA full cache write on every call, no reads
Editing tool names, descriptions or schemasClaude invalidates the whole cache; OpenAI's prefix stops matching
Changing tool_choice or adding or removing images (Claude)Message cache invalidated
Changing thinking or output_config.effort (Claude), or reasoning.effort, text.verbosity or text.format (OpenAI)Prefix changes from that point
Extending an existing message instead of appending a new one (OpenAI)The old breakpoint now sits inside a message and is not reused
Switching an OpenAI conversation from implicit to explicit-only modeThe earlier implicit entry is not found
JSON keys reordered by your language runtime (Claude)Cache breaks; the docs name Swift and Go
Parallel requests sent before the first response starts (Claude)No entry exists yet, so each request writes its own
Compaction or truncation of historyThe rewritten prefix starts a new cache

Caches are also scoped. OpenAI does not share caches across organizations or regional processing boundaries. Claude isolates caches per workspace on the Claude API, so the same prompt in two workspaces is cached twice.

How to measure the saving from the usage fields

Log the cache fields on every response, then compute the hit rate as cached tokens divided by total input tokens, grouped by endpoint or day. A tracing tool such as Langfuse can store these per request.

On OpenAI, input_tokens includes everything. Ordinary tokens are input_tokens - cached_tokens - cache_write_tokens, and the guide's cost formula weights cached tokens by the read multiplier and write tokens by the write multiplier.

On Claude, input_tokens counts only tokens after the last breakpoint. The total is cache_read_input_tokens + cache_creation_input_tokens + input_tokens. A request with 100,000 cached tokens and a 50-token question reports input_tokens: 50 for a total of 100,050.

def claude_input_cost(u, base_per_mtok, read_mult=0.1, write_mult=1.25):
    weighted = u.input_tokens + u.cache_read_input_tokens * read_mult \
        + u.cache_creation_input_tokens * write_mult
    return weighted * base_per_mtok / 1_000_000

Set read_mult to the multiplier for your model: 0.05 on Claude Opus 5.5 and Sonnet 5.5. For 1-hour writes, use 2.0, and read the split from the cache_creation object, which reports ephemeral_5m_input_tokens and ephemeral_1h_input_tokens separately.

OpenAI's guide also works through the case of a shared prefix just under the minimum. With a 1,024-token minimum, a 0.1× read and a 1.25× write, padding the prefix with useful stable material up to 1,024 tokens costs less across 10 requests once the original prefix is at least 221 tokens. A prefix of 102 tokens or fewer never benefits under those assumptions.

Frequently asked questions

Does prompt caching change the model's answers?

No. OpenAI states that caching does not change how output tokens are generated, and identical requests can still produce different outputs. Anthropic states that caching has no effect on output generation. Only the cost and speed of processing the input change.

Do cached tokens count toward rate limits?

On OpenAI, yes: cached input tokens still count toward tokens-per-minute limits. Anthropic's docs list better rate limit use as a reason for the 1-hour cache because cache hits are not deducted against the rate limit. For Gemini explicit caching, the standard generateContent limits apply and token limits include cached tokens.

Can I clear a cache before it expires?

Not on OpenAI or Claude; both docs say manual clearing is not available and entries expire on their own. Gemini explicit caches are named objects, so you can delete one or shorten its TTL through the caches API.

Should I send my first requests in parallel to warm the cache?

No. Claude's docs note that an entry becomes available only after the first response begins, so send one request, wait for it to start, then fan out. OpenAI offers `prompt_cache_options.prewarm` on GPT-5.6 and later to write the cache without generating output, billed at the cache-write rate, and Claude's docs describe a pre-warming option for system prompts and tools.

Sources

  1. 1.Prompt caching | OpenAI APIOfficial docsPrimarydevelopers.openai.com
  2. 2.Prompt caching - Claude Platform DocsOfficial docsPrimaryplatform.claude.com
  3. 3.Context caching  |  Gemini API  |  Google AI for DevelopersOfficial docsPrimaryai.google.dev
  4. 4.ai.google.dev/gemini-api/docs/cachingWeb
  5. 5.ai.google.dev/gemini-api/docs/caching.md.txtWeb
  6. 6.ai.google.dev/gemini-api/docs/generate-content/cachingWeb
  7. 7.ai.google.dev/gemini-api/docs/generate-content/caching.md.txtWeb
  8. 8.ai.google.dev/gemini-api/docs/pricingWeb

Spotted an error? See our corrections policy.

Enjoyed this? Get the weekly brief.

New guides, Project & Tool of the Week and the AI developments that matter. One email, no spam.

Read next