AI AI-07.07
Prompt caching and cost control
Reuse the processed form of repeated prompt prefixes: put stable content first for cache hits, and account for every token so you know where the money goes.
The big idea
Before a model writes a single token, it processes the whole prompt, computing keys and values for every token in every layer ( Context windows and the KV cache ). In many applications most of that prompt is identical from call to call: the same system prompt, the same tool definitions, the same 30-page document the user keeps asking about. Processing it again every time wastes money and time.
Prompt cachingA provider feature that stores the processed form (the KV cache) of a prompt prefix so later requests starting with exactly the same prefix can reuse it, at a lower price and latency. stores the processed form of a prompt's beginning and reuses it when the next request starts with exactly the same tokens. Cached tokens are billed at a fraction of the normal input price and skip most of the processing time. The catch is in the word "exactly": the cache only matches an identical prefix, so the order of your prompt decides whether you get any benefit at all.
Think of a lecturer who prints the same 30-page handout for every class. Reprinting it each time costs the same as the first time. Keeping a stack ready means each class only needs today's one-page worksheet printed. But if the date is printed at the top of page one, every stack is out of date tomorrow.
How it works
Prefix matching
The cache works on prefixes: a request benefits only for the tokens, from the very start, that are identical to a cached prompt. One changed token early on and everything after it is a miss. Providers typically build the prefix from tool definitions, then the system prompt, then messages, and you mark where cacheable sections end, or the provider does it automatically.
So order the prompt from most stable to least stable:
- Tool definitions and system prompt: identical for every user.
- Long shared context: the document, the codebase summary, the few-shot examples.
- Conversation history: grows, but earlier turns do not change.
- The new question and anything request-specific, last.
Cache killers
- A timestamp, request ID or user name at the top of the system prompt.
- Tool definitions generated in a different order each time, or with a changing description.
- The question placed before the document.
- Editing earlier history, such as trimming old turns, which changes everything after the edit.
If you need today's date or the user's name, put it after the stable parts.
Lifetime and write cost
Caches expire after a short time without use, minutes by default, so caching pays when requests sharing a prefix arrive close together: a chat conversation, an agent loop, a batch of questions about one document. Some providers charge a premium to write a prefix into the cache. A prefix written once and never read again costs more than no caching at all.
Token accounting
You cannot control what you do not measure. API responses report tokens per request: uncached input, cache writes, cache reads and output. Log them with the feature, prompt version and user tier, price them, and look at the totals by feature. Common findings: one feature dominates the bill; output tokens cost several times more per token than input, so long answers matter; a cache that was meant to be hit is not.
Try it
Prices and multipliers are adjustable assumptions; set them to your provider's numbers.
Try this:
- At the defaults (stable parts first, a 30,000-token document, 10 questions), 89 percent of input tokens are read from cache and input cost falls from about 1.11 to 0.25 dollars, 78 percent less.
- Switch to "timestamp at the top". A 20-token line that changes every request breaks the prefix: nothing is read from cache, and because every request pays the write premium, caching now costs 25 percent more than no caching.
- Go back to stable first and set questions to 1. A single request writes the cache and never reads it: caching costs more. Set it to 30 and savings rise to about 85 percent. Caching pays for repetition.
Going deeper
Accounting in code
# Token accounting: price every request from its usage numbers and see where the money goes.
# Usage records look like what APIs return; prices are made-up round numbers per 1M tokens.
from collections import defaultdict
PRICE = {"input": 3.00, "cache_write": 3.75, "cache_read": 0.30, "output": 15.00}
log = [ # feature, uncached input, written to cache, read from cache, output tokens
("doc_chat", 500, 36000, 0, 400), # first question about a document: cache written
("doc_chat", 500, 0, 36200, 350), # follow-ups read the document from the cache
("doc_chat", 600, 0, 36600, 420),
("doc_chat", 550, 0, 37000, 380),
("triage", 1800, 0, 0, 60), # short prompt, no cacheable prefix
("triage", 1750, 0, 0, 55),
("summary", 9000, 0, 0, 2500), # long outputs dominate here
]
def cost(inp, write, read, out):
return (inp * PRICE["input"] + write * PRICE["cache_write"]
+ read * PRICE["cache_read"] + out * PRICE["output"]) / 1e6
by_feature = defaultdict(lambda: [0, 0.0, 0.0]) # calls, cost, cost if nothing were cached
for feature, inp, write, read, out in log:
f = by_feature[feature]
f[0] += 1
f[1] += cost(inp, write, read, out)
f[2] += cost(inp + write + read, 0, 0, out)
print(f"{'feature':10} {'calls':>5} {'cost':>9} {'uncached':>9} saved")
for feature, (calls, c, u) in by_feature.items():
print(f"{feature:10} {calls:5} {c:9.4f} {u:9.4f} {100 * (1 - c / u):4.0f}%")
total = sum(f[1] for f in by_feature.values())
out_share = sum(o * PRICE["output"] / 1e6 for *_, o in log) / total
print(f"total {total:.4f} dollars; output tokens are {100 * out_share:.0f}% of it")Output
feature calls cost uncached saved
doc_chat 4 0.1976 0.4671 58%
triage 2 0.0124 0.0124 0%
summary 1 0.0645 0.0645 0%
total 0.2745 dollars; output tokens are 23% of it The document chat saves 58 percent, even counting the first request's cache write. Triage and summaries save nothing: triage has no long shared prefix, and the summary's cost is mostly its long output. Caching cannot help output tokens; shorter answers can ( Latency and cost budgets ).
Other cost levers
Caching is one lever among several: route easy requests to cheaper models ( Routing, cascades and cost optimization ), trim context you do not need ( Context engineering ), cap output length, and use batch APIs for work that can wait, which providers often discount. Measure first, then pull the lever that matches where the money actually goes.
Trade-offs
| Option | Wins when | Loses when |
|---|---|---|
| Caching with stable-first order | Large input savings and lower latency on repeated prefixes | Needs disciplined prompt order; expires after minutes idle |
| No caching | Nothing to manage; no write premium | Pays full price for repeated context every call |
| Long-lifetime cache | Hits survive gaps between requests | Higher write price; wasted if traffic is sparse |
| Shorter prompts instead | Saves on every call, cached or not | Risk of dropping context the model needs |
Common mistakes
- A timestamp or request ID at the top of the system prompt, silently disabling every cache hit.
- Putting the user's question before the shared document.
- Assuming caching works without checking the cache-read numbers in the usage data.
- Caching prompts that are never repeated within the lifetime, paying write premiums for nothing.
- Optimising input tokens while long outputs make up most of the bill.
In the wild
Anthropic
Prompt caching (documentation) (opens in a new tab)The documentation explains that cache prefixes are built in the order tools, system, then messages, and that a request reuses the cache only for an identical prefix. The default cache lifetime is 5 minutes, with a longer option at a higher write price. Cache writes are billed above the base input price and cache reads well below it, and each response reports how many tokens were written to and read from the cache, which is what you monitor to confirm caching works.
Check yourself
-
Your system prompt starts with 'Current time: 14:03:27'. What happens to caching?
Show answer
B. Every request has a different prefix from the first token, so nothing is read from cache Caching matches exact prefixes. A changing first line makes every request a miss. Move it to the end.
-
Which order maximises cache hits for a document Q and A app?
Show answer
B. System prompt and tools, document, history, then the question Most stable first, most variable last, so consecutive requests share the longest prefix.
-
A batch job sends each prompt once, an hour apart, with caching on and a write premium. What is likely?
Show answer
B. Higher cost: each prefix is written but expires before it is read Caching pays for repetition within the lifetime. One-off prompts pay the write premium and never collect.
-
Accounting shows one feature's cost is mostly output tokens. Will prompt caching help it much?
Show answer
B. No: caching only discounts repeated input; cap or shorten the outputs instead Caching reuses processed input. Output tokens are generated fresh and billed in full every time.
Recap
- Prompt caching reuses the processed form of an identical prompt prefix, cutting input cost and latency.
- Order prompts from most stable to least: tools and system, shared context, history, then the request.
- Anything that changes early in the prompt, such as a timestamp, breaks every hit after it.
- Caches expire within minutes and writes may cost extra, so caching pays only for repetition.
- Log and price tokens per request and feature; check cache reads, and remember output tokens are not cached.