Cruxly

Cruxly › AI engineering › LLM Backend Infrastructure

Prompt Caching: Paying for the Same Tokens Once

prompt layout is the cache key, and one timestamp can cost you all of it

Open the interactive lesson

Prompt: a support assistant sends every request with the same 20,000-token prefix — a long system prompt, tool definitions, and a product manual — followed by a few hundred tokens of the user's actual question. The bill is dominated by input tokens the model has already seen thousands of times. Cut it, and say exactly what could silently undo the saving.

30 minutes first. The naive answer is "turn on caching." The real answer is that caching only works if the prompt is laid out for it, and most production prompts are not.

What is actually being cached

How the major providers expose it (as documented in 2026 — check current docs, the multipliers change):

AnthropicOpenAI
Turned on byMarking breakpoints with cache_control (or automatic mode)Automatic, by default
Cache read price~0.1× the base input rate (lower on some newer models)~0.1× on most models (lower on some)
Cache write price1.25× for the 5-minute cache, 2× for the 1-hour cache1.25× on newer models; no surcharge on older ones
Lifetime5 minutes (default) or 1 hour, refreshed on each hitOlder models: ~5–10 minutes idle, or up to 24 hours with extended retention; newer: ~30 minutes after last use
Minimum prefixRoughly 512–4,096 tokens depending on the model1,024 tokens
Where you see itcache_read_input_tokens, cache_creation_input_tokenscached_tokens in the input-token details

Last verified 2026-10-31 against each provider's docs: Anthropic reads cost 0.05× on Claude Opus 5.5 and Sonnet 5.5 and 0.025× on Fable 5.1 (0.1× elsewhere); a single top-level cache_control field turns on automatic caching, which moves the breakpoint forward as the conversation grows. OpenAI documents, for GPT-5.6 and later (its examples use GPT-6.1 Sol), an explicit mode (prompt_cache_options.mode) that caches only developer-placed breakpoints, and a 12h retention option written at 2.5× the uncached input rate; its reads are 0.1× on most models and 0.05× on GPT-6.1 Sol and Terra, writes are 1.25× for the default 30-minute lifetime, and the minimum cacheable prompt is 1,024 tokens. Multipliers change, so re-check before quoting.

:::key The one fact that drives the whole design A cache hit needs the prompt to be byte-for-byte identical up to that point. Every other decision in this lesson follows from that. :::

Prompt layout is the cache key

Order the prompt from most stable to least stable. On Anthropic the cache prefix is built in a fixed order — tools, then system, then messages — and a change at one level invalidates that level and everything after it. Changing a tool definition invalidates the whole cache.

system:   "Today is 2026-10-06 14:32. You are helping {user_name}..."   ← changes every request
          + 15,000-token product manual
tools:    [list built from a dict — order differs between deploys]
tools:    fixed list, fixed order, defined once
system:   instructions + 15,000-token manual   ← identical for every user, every day
messages: "Context: today is 2026-10-06, user is {user_name}." + the question

The silent cache-killers that show up in real code:

The arithmetic, and choosing the TTL

Caching costs a little extra on the first request (the write) and saves a lot on every later one (the reads). Work out when it pays off before claiming it does. Using Anthropic's multipliers, for a prefix of size P reused n times:

@@ 1 | 5-minute cache: write 1.25×, read 0.1× Cost with caching = 1.25P + 0.1P × (n − 1). Without = nP. It wins once n > 1.3 — from the second request onward.

@@ 2 | 1-hour cache: write 2×, read 0.1× Cost with caching = 2P + 0.1P × (n − 1). Wins once n > 2.1 — from the third request, but it survives quiet periods.

@@ 3 | The support assistant in the prompt 20,000-token prefix, steady traffic. Without caching every request pays for 20,000 input tokens. With a warm cache, each request pays about 20,000 × 0.1 = 2,000 token-equivalents for the prefix plus its own few hundred — roughly an 85–90% cut in input cost, and a shorter time-to-first-token.

Choosing the lifetime is a traffic question, not a preference:

:::warn A cache that is written but never read is pure loss Marking a prefix that is only ever used once — a one-off document, a unique per-user prompt — costs 1.25–2× its normal price for no benefit. Cache what is reused, not everything. :::

Measuring it, and the alert that catches a regression

Never assume caching works — read it from the response. Every response reports how many input tokens were read from cache, how many were written, and how many were processed normally. If a prefix is shorter than the minimum, providers generally just don't cache it, with no error — the usage fields are the only signal.

Three more traps that show up under real traffic:

Google's Gemini works differently again: it has automatic (implicit) caching, plus explicit context caches you create and pay to store over time — a different cost curve from the write-surcharge model above.

Prompt caching versus the other caches in this track:

Prompt caching (this lesson)Prefix caching (Inference Serving)Semantic caching (Governance)
Who runs itThe API providerYou, on your own GPUsYou, in front of the model
What is reusedModel state for an identical prefixModel state for an identical prefixA whole previous answer for a similar question
RiskNone to correctness — output is still freshly generatedNone to correctnessCan return the wrong answer for a question that only looks similar

The first two are the same idea, one bought and one built. Semantic caching is a different trade: it skips the model entirely, which saves more but can be wrong.

How to say it in the interview

"The provider can reuse work for a prompt prefix it has seen before, but only an exact prefix match counts. So the design question is prompt layout: everything that never changes goes first, everything that changes per request goes last, and one dynamic value near the top — a timestamp, a user name — turns every request into a cache miss."

Checklist

Practice this interactively
Share this lessonWhatsAppLinkedInX

Related lessons