The Cache-Write Tax Nobody Budgets For
Caching used to be a strict discount, no exceptions. Set a stable prefix, get cheaper reads, no downside. That was true of every model generation before GPT-5.6. It stopped being universally true the moment that generation shipped, and the number of teams that have actually re-run their caching math since is, based on the questions this site sees, a lot smaller than the number of teams whose workloads quietly moved onto the newer models.
What actually changed, precisely
GPT-5.6 and later models bill the tokens written into the cache at a separate cache-write rate, 1.25x the ordinary input rate, instead of at the input rate itself. On every earlier generation, writing a prefix cost nothing beyond the input rate you were paying for those tokens anyway; only the discount on later reads was new money. Every GPT-6 model kept the write rate, so this is now the norm rather than a quirk of one generation. It isn't a subtle repricing of an existing fee; it's a genuinely new line item, and it changes the shape of the decision from "should I cache this" (almost always yes, on older models) to "will this specific prefix get read back enough times to be worth writing" (a real question, on the newer ones).
Why this is easy to miss during a routine model upgrade
A team moving from GPT-5.4 to GPT-5.6 for the recency improvement, or because it's simply the newer, more capable option, isn't necessarily thinking about caching at all during that decision — caching was a solved, settled part of the architecture, not something anyone expected to need revisiting. The write charge doesn't announce itself with an error or a warning; it shows up, if it shows up at all, as a bill that's somewhat higher than expected, for reasons that take real investigation to trace back to a single line item that used to cost nothing extra.
The arithmetic that actually determines whether you're paying a real tax or not
The write markup only turns into a real tax when a given prefix isn't read back often enough to offset what the write itself cost. Picture the ends of a spectrum: a customer-support bot's shared instruction set, written once and hit by every incoming ticket, earns back its write cost within the first handful of tickets and is essentially free after that — as long as the tickets keep coming. On GPT-5.6 and later, a cached prefix stays eligible for reuse for 30 minutes after its most recent write or read, and each reuse refreshes that lifetime without another write charge; a quiet overnight gap means the first ticket of the morning pays for the write again. A prefix assembled fresh for each call — because a piece of per-call data sits near the top of the prompt — never accumulates any reads against it at all, so the write charge sits on the invoice with nothing on the other side of the ledger to cancel it out.
The workloads most likely to be quietly overpaying
Short-lived sessions with little reuse, aggressively rotated prompt_cache_key values, prompts that put request-specific content early rather than at the end, and bursty traffic with gaps longer than the cache's lifetime are the patterns most likely to be paying the new write charge without collecting the corresponding savings. None of these were necessarily wrong choices on an older model generation, where writing cost nothing extra and this specific failure mode simply couldn't happen. They become genuine liabilities the moment the same architecture runs on a model that charges for writing. The last pattern now has a remedy of its own: since October 20, 2026, the Responses API offers a 12-hour cache lifetime that keeps an entry eligible across long gaps, at 2.5x the input rate per write instead of 1.25x — a bigger write tax, paid far fewer times, and worth it only when the reads it saves add up.
Restructuring a prompt to actually benefit from caching
Often the real fix isn't a pricing decision at all but a prompt-structure one: relocate whatever changes from call to call — a request id, a piece of user state, anything unique to that specific turn — down toward the bottom of the prompt, so the bulk of it up top never changes and can actually be recognized as the same prefix every time. That's a rewrite of how the prompt gets assembled, not a change to any setting, and it's often the entire difference between a prompt that's structurally incapable of being cached and one that starts paying for itself on the very next call.
Why "just disable caching" isn't usually the right response either
Faced with an unexpected write charge, the reflexive fix might be to stop caching altogether and accept the plain uncached rate on every request. That's rarely the right move — for any workload with genuine reuse, caching under the new pricing still pays off, often quickly; the problem isn't caching itself, it's a workload whose actual traffic pattern doesn't have the reuse the caching strategy assumed. Fixing the traffic pattern, or restructuring the prompt so reuse becomes possible, is almost always a better answer than abandoning a mechanism that, correctly used, remains a genuine saving even under the new charge.
The one number that actually settles the question
Rather than reasoning about this qualitatively, the real answer is computable directly from the published write and read multipliers — how many later reads a given write needs before it's paid for itself — and it's worth running that number for your actual workload, with the prompt caching savings calculator, rather than assuming either "caching is still obviously worth it" or "caching isn't worth it anymore" without checking. Both instincts are wrong often enough, in opposite directions, that the arithmetic is worth the few minutes it takes. The answer also differs by model: GPT-6.1 Sol discounts cached reads more deeply than its siblings, at 0.05x its input rate against 0.1x, so the same prefix pays back its write slightly sooner there.
Why "it worked fine on the old model" is exactly the wrong evidence to trust
The most dangerous version of this mistake isn't a team that never thought about caching economics — it's a team that thought about it once, correctly, on an older model, and is now carrying that conclusion forward onto a newer one without re-deriving it. "Caching has always saved us money here" was true, and it was true specifically because writing cost nothing extra on the model that conclusion was based on. Moving the same architecture onto a model where that's no longer the case doesn't retroactively make the old conclusion wrong — it makes it stale, in a way that looks identical to still being correct until someone actually checks.
What this looks like from the outside, on an actual invoice
A team that hasn't re-run this math typically notices something vague rather than something specific — a monthly bill that's "a bit higher than expected" for reasons nobody can immediately point to, after a model migration that otherwise seemed to go smoothly. The cache-write charge rarely announces itself as a distinct, obviously-labeled line item large enough to jump out; it's diffused across every single request that writes to cache without reading back enough, which makes it exactly the kind of cost that's easy to miss in aggregate and only becomes visible once someone deliberately goes looking with the usage object in hand, request by request.
A concrete habit that catches this early
Checking cache_write_tokens and cached_tokens — both under usage.input_tokens_details — on a sample of real requests immediately after any model migration, not weeks later and not only when a bill looks unusual, is the specific, cheap habit that catches this class of surprise while it's still small. OpenAI now makes it easier than it was: the Prompt Caching dashboard tracks hit rate and reads per write over time, filterable by model and service tier, and Prompt Cache Diagnostics on the Responses API names the reason for a specific miss. A few minutes with either, against a workload already being migrated for other reasons, turns a vague, hard-to-diagnose bill increase into a specific, actionable finding about one caching pattern. The prompt caching reference has the full mechanics.
Verified 2026-10-28 against CodexHow facts module (src/data/facts/) — see /about/#accuracy.