Cache Tokens Explained
Updated
TL;DR
Table of Contents
The most expensive tokens on your AI bill are usually ones the model has already read. Providers give a big discount on content they've already processed, about 90% off on Claude and OpenAI, and closer to 98% off on DeepSeek. Whether you actually get that cheap rate depends mostly on one thing, the order you put things in your prompt.
I ignored this for a long time, honestly. Every usage block had fields like cache_read_input_tokens sitting right there, and I skimmed past them because nothing in my code referenced them. It only clicked when I traced an agent session and realized I was paying full price for the same few thousand tokens, over and over, dozens of times in one afternoon. Once you see it, you can't unsee it, and the fix is mostly habits rather than code.
First, what is a token?
A token is a chunk of text. It might be a whole word, part of a word, or a punctuation mark on its own. Models don't read letters the way we do, they read tokens, and everything you send plus everything they generate gets counted in them. That count is what you're billed on.
That's all you need for this post. If you want the longer story of how tokens and context windows fit together, I went deep on that in A million token context window isn't what you think it is. Here, the one thing to hold onto is that text goes in as tokens and you pay per token.
So what are cache tokens?
Think about how you actually use a model. You almost never send a completely new prompt. The system instructions, the tool definitions, the document you pasted in, the earlier turns of the conversation, all of that gets shipped again on every request, and only your newest message changes at the end.
It's like picking up a book you're halfway through. If you had to re-read the first hundred pages every time you sat down, just to get back to where you were, you'd waste a lot of effort before doing anything useful. That's what a model does by default. It processes your prompt from the very start on every request, including parts it saw a minute ago.
Caching fixes this. The first time the provider processes a chunk of your prompt, it saves the processed result, like a bookmark in the book. The next request that starts with that same chunk reuses the saved version instead of redoing the work. Those reused tokens are your cache tokens, and they're billed at a big discount.
Two things show up on your bill, and it helps to name them now, because every provider uses slightly different words for the same two things.
- A cache write happens the first time, when the provider processes your content and saves it. The bookmark goes in.
- A cache read, also called a cache hit, is every time after that, when the provider finds the bookmark and reuses it.
Why cache tokens cost less, and the catch
A cache read is cheap because the provider is doing far less work. It already did the expensive part once and passes the savings on to you. So far, so good.
The catch is that a cache write often costs more than a normal input token. Saving that copy takes extra work on the provider's side, so some of them charge extra for it. When I first saw a "cache write" line item priced above the normal input rate, I assumed it was a mistake. It wasn't, and it took me an embarrassing amount of time to understand why anyone would agree to that.
What finally made it click for me was thinking of caching as a bet. You pay a little extra up front, hoping you'll read that content back enough times to come out ahead. A handful of cheap reads pays off one pricey write with plenty left over. Send a one-off prompt you'll never reuse, and you lose the bet, paying the extra and collecting nothing. Caching rewards repetition and quietly punishes constant change.
How the big providers price cache tokens
The core idea is the same everywhere. What differs is how much control you get and how the bill is split. Here's a rough map, and please treat the numbers as a snapshot, because these pages change constantly.
| Provider | How it turns on | Cache read | Cache write |
|---|---|---|---|
| Anthropic (Claude) | You mark it, or auto-caching | 10% of normal input | 1.25x input (5-min), 2x (1-hour) |
| OpenAI | Automatic, above 1,024 tokens | ~10% of normal input on current models | No separate charge |
| DeepSeek | Automatic, on by default | About 1/50th of a cache miss | No separate charge |
| Google Gemini | Automatic, plus manual caches you create | About 90% off normal input | Manual caches add a storage fee |
Anthropic (Claude)
Claude gives you the most direct control. You can place a cache_control marker on the part of the prompt you want cached, or let automatic caching handle it for you. Reads cost 10% of the normal input price, a 90% discount. Writes cost 1.25x for the standard 5-minute cache and 2x for a 1-hour one.
That 5-minute clock matters more than any other number here. Every cache hit resets the timer for free, so as long as you keep sending requests, you stay on the cheap rate. Go quiet longer than the window, and the bookmark is gone. Your next request pays full input price plus the extra write cost to rebuild everything. Anthropic's docs point out something easy to miss, too. The clock starts at the beginning of your request, so if a response takes 4 minutes to arrive, your next request has to come within about a minute of it finishing.
Claude also reports exactly what happened in every response:
"usage": {
"input_tokens": 50,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 100000,
"output_tokens": 503
}cache_read_input_tokens is what you reused cheaply, cache_creation_input_tokens is what you paid extra to write, and input_tokens is the fresh, uncached part, usually just your latest message. In that example, 100,000 tokens came from cache and only 50 were new. Caching working exactly as intended.
OpenAI
OpenAI is the hands-off one. Caching turns on automatically for any prompt above 1,024 tokens, with no markers and no settings to change. Reused tokens appear in the usage block as cached_tokens. The discount used to be 50%, but on current models cached input costs about a tenth of the normal price, roughly the same discount Claude gives. Unlike Claude, OpenAI charges no extra for writes, so a cache miss costs you nothing extra.
The price of that simplicity is control. You can't set how long the cache lives or see what's in it. The only thing you control is your prompt structure, keeping the front of it identical across requests. OpenAI does offer an optional prompt_cache_key setting to group similar requests and improve hit rates, but that's all you get.
DeepSeek
DeepSeek is the clearest example of the whole idea, because the gap between a hit and a miss is huge. Its caching is automatic and on by default, with nothing to set up and no charge for writes. On DeepSeek V4 Flash, a cached input token costs $0.0028 per million against $0.14 per million for an uncached one. That's fifty times cheaper for the exact same text, purely because the model saw it recently.
The usage response shows the two separately as prompt_cache_hit_tokens and prompt_cache_miss_tokens. One warning from DeepSeek's own docs, the cache works on a best-effort basis and needs the start of your prompt to match exactly, so if a system prompt changes by even one character between calls, you get a miss.
Google Gemini
Gemini runs two systems side by side. Implicit caching, the automatic kind, is on by default for Gemini 2.5 and newer models, and Google passes the savings to you when a request hits an existing cache. The minimum is 2,048 tokens on the 2.5 models and 4,096 on newer ones, and hits show up as total_cached_tokens in the usage object.
Explicit caching is the version you turn on yourself. You create a cache, load your big shared content into it once, set how long it should live, and use it from many requests. Cached reads are about 90% off the normal input price. The odd part is the storage fee. You pay per token, per hour, for as long as the cache exists. On Gemini 3.1 Pro, storing a million tokens for an hour costs $4.50, more than two full-price reads of the same content. An unused cache is like a taxi meter that keeps running, so explicit caching only pays off when many requests reuse the same large content in a short time.
INFO
Model names, prices, and minimum token limits move fast. Treat every number here as a snapshot, and check each provider's live pricing page before you use it for real budgeting.
How to actually pay the cheap rate
If you take one rule from this post, take this one. Put the parts that stay the same at the front, and the parts that change at the end.
Caching matches on the beginning of your prompt and stops at the first thing that differs. A prompt shaped like this caches well:
[ system instructions ] <- same every time
[ tool definitions ] <- same every time
[ reference document ] <- same every time
--------------------------------- cache ends here
[ the user's new question ] <- changes every timeEverything above the line gets reused cheaply. Only the new question at the bottom is processed fresh.
A few habits follow from that rule.
Don't sneak a changing value into the stable part. This is the mistake I'd bet nearly everyone makes once. A timestamp, a random ID, the user's name dropped near the top of the prompt, and your "same every time" section stops being the same. The cache misses every time, so you pay for a fresh write on every request and never get a cheap read. My own zero-hit-rate mystery turned out to be a date string I'd pasted into the system prompt "temporarily", and it stayed there for a week.
Reach the minimum. Providers only cache prompts above a floor, 1,024 tokens on OpenAI and Claude, 2,048 or more on Gemini. If your reusable content sits just under the line, it won't cache at all. Adding more useful content to get past the line can actually save money, because cheap reads pay back the slightly bigger write.
Reuse it while it's warm. Caches expire within minutes unless you're paying for longer. Sending your requests close together keeps the cache alive, since hits refresh it for free. Long gaps let it expire and force a fresh write.
Watch the usage fields. Every provider reports cache reads and writes in the response, under whatever names the table above lists. If you expected reads and you're seeing writes on every call, something in your "stable" section is quietly changing.
CAUTION
The timestamp trap catches almost everyone once. If your cache hit rate is mysteriously zero, check whether something that changes, a date, a session ID, a counter, crept into the front of your prompt. That one detail wipes out the cache for everything after it.
Cutting cache costs when you use a coding agent
Most people reading this won't call these APIs by hand. They use a coding agent like Claude Code, OpenCode, or Cursor. You're still paying for cache tokens, the agent just handles them behind the scenes, so you can't control this directly. What you control is what you feed the agent.
Every request an agent sends looks roughly like system prompt + tool definitions + context files + conversation history + your new message. Everything except your new message is the stable part it tries to cache, and two things make that expensive. The prefix is huge before you've typed a word, and every change to it forces a full-price rewrite. A study on coding agent token overhead measured Claude Code sending around 33,000 tokens of setup text before you've asked anything. A 72KB CLAUDE.md added about 20,000 tokens to every request, and five modest MCP servers added another 5,000 to 7,000.
So what actually helps? Trimming your CLAUDE.md or AGENTS.md helps the most, since every line in it rides along on every request. The same goes for MCP servers you aren't using this session, whose tool definitions sit right at the front of the prefix.
Second, leave your config alone mid-task. Editing a context file or turning an MCP server on or off halfway through a session rewrites the front section, which wipes out the cache for everything after it. Set your context up before you start, then let it be while you work.
Third, work in bursts, not trickles. The cache lives for minutes, and hits refresh it for free, so a flowing back-and-forth keeps you on the cheap read rate the whole time. Walk away for an hour, and the agent rebuilds the entire prefix from scratch when you come back.
Be careful with compaction and clearing, too. Compaction is when the agent summarizes the conversation to make it fit the context window. Either way, whether the agent does it or you clear things yourself, the prefix resets and you're back to a full-price write. Both are sometimes worth it to shrink a bloated context, just know that each one starts you over with that expensive write.
Your choice of model changes the numbers too. Cache prices follow the base model's price, so the same prefix is cheaper to cache on a cheaper model. Sending a one-line question to your most expensive model out of habit costs you either way.
One comparison from that same study is worth knowing. OpenCode sent about 7,000 baseline tokens for the same task where Claude Code sent 33,000, and a smaller baseline means smaller, cheaper writes. The fair warning is that Claude Code groups its tool calls into fewer back-and-forths, so on a long task it can end up using fewer tokens overall. It's not a clean win either way. Your workload decides.
One thing I'd steer you away from is switching to your own API key purely to "save money." For heavy day-to-day coding, a flat subscription is almost always cheaper than paying per token, because top-model API usage adds up fast. Your own key does make the token costs visible, which is genuinely useful for learning where your money goes, and I've written before about running OpenCode with your own key or Copilot with a custom key. Just don't mistake visibility for a discount.
Wrapping up
Cache tokens reward structure, and the mental model fits in one sentence. A big stable part, kept identical and reused quickly, is cheap. Small edits, long gaps, and constant config changes mean you keep paying for the expensive write again.
You don't need to be an expert to benefit from any of this. Put the stable stuff first, put the changing stuff last, and reuse it while it's warm. That one habit is most of the savings, whether you're calling an API directly or living inside a coding agent all day.