OpenAI's 12-hour prompt cache pays off when a prefix is read at least twice inside 12 hours by requests spaced too far apart for the default 30-minute cache. A write to it costs 2.5 times the input rate and a read 0.1 times (0.05 on GPT-6.1 Sol and Terra), so the first read nearly covers the premium and the second puts you ahead1. OpenAI added it to the Responses API on 20 October 2026, describing it as a way to keep "shared instructions, tools, and context cached longer"2.
The rest of this guide is the arithmetic, the request shape, the comparison with Anthropic and Gemini, and how to confirm in production that you are paying for reads rather than writes.
What OpenAI changed
On GPT-5.6 and later models, prompt caching on the Responses API has two lifetimes, set with prompt_cache_options.ttl: "30m", the default, and "12h". Each can be overridden on an individual cache breakpoint with prompt_cache_breakpoint.ttl. These settings are separate from prompt_cache_retention, the older control that earlier models use1.
| 30-minute (default) | 12-hour | |
|---|---|---|
| Setting | ttl: "30m" | ttl: "12h" |
| Write price | 1.25x input | 2.5x input |
| Read price | 0.1x input; 0.05x on GPT-6.1 Sol and Terra | Same |
| Minimum lifetime for read pricing | 30 minutes | 12 hours |
| Minimum prefix | 1,024 visible input tokens | Same |
Three details in the guide shape how you use it1:
- The lifetime is a minimum, not a contract for hits. "Minimum lifetime" is how long an entry is guaranteed to qualify for read pricing. OpenAI may keep entries longer, and the guide says the minimum does not guarantee that every request reuses stored tensors.
- Write pricing replaces input pricing. A written token is billed at 1.25x or 2.5x instead of the input rate, not in addition to it.
- Reads do not restart the 12-hour clock. The guide describes a 30-minute read of an entry with 12-hour coverage as moving expiry to the later of the existing expiry and 30 minutes after the read, with no new write charge. Plan for one 12-hour write per 12 hours of reuse.
For models before GPT-5.6 nothing changed: prompt_cache_retention still takes in_memory or 24h on the models that support it, and those models carry no separate cache-write charge1. The pricing page lists cache-write rates only for the GPT-5.6 and GPT-6 models3.
Break-even arithmetic
Call the write multiplier w, the read multiplier r, and the number of reads one write serves N. Without caching, one write plus N reads would cost (1 + N) units of input. With caching they cost w + rN. Caching is cheaper once N > (w − 1) / (1 − r).
| Cache | Write w | Read r | Break-even reads | Pays from |
|---|---|---|---|---|
| OpenAI 30-minute | 1.25 | 0.1 | 0.28 | The first read |
| OpenAI 12-hour | 2.5 | 0.1 | 1.67 | The second read |
| OpenAI 12-hour, GPT-6.1 Sol or Terra | 2.5 | 0.05 | 1.58 | The second read |
| Anthropic 5-minute | 1.25 | 0.1 | 0.28 | The first read |
| Anthropic 1-hour | 2 | 0.1 | 1.11 | The second read |
| Anthropic 1-hour, Opus 5.5 or Sonnet 5.5 | 2 | 0.05 | 1.05 | The second read |
The formula ignores output tokens, which are billed the same either way, and assumes every read finds the entry. The second assumption is the one that fails in practice, and it is where the choice of lifetime matters.
Why the 30-minute default can lose for sparse traffic
The 30-minute write pays from the first read, but only if a read arrives while the entry is alive. Traffic that reuses a prefix every two hours, such as a scheduled summary job, a support desk overnight, or an agent a developer resumes after lunch, can find the entry gone. In the worst case every request pays the 1.25x write and never reads, which costs more than no caching at all. That is the gap the 12-hour lifetime fills.
How to enable it
Prompt caching is on by default for supported models. In OpenAI's implicit mode the platform places one breakpoint at the end of the latest eligible message; in explicit mode you place every breakpoint, and a request with none creates no cache writes. A request can create up to four cache writes, and in implicit mode the automatic breakpoint uses one of them1.
To put a whole request on the 12-hour lifetime, set the request-level option:
{
"model": "gpt-6.1-sol",
"prompt_cache_options": { "ttl": "12h" },
"input": [
{ "role": "developer", "content": [{ "type": "input_text", "text": "<shared policy, tools and examples>" }] },
{ "role": "user", "content": [{ "type": "input_text", "text": "Summarize ticket 4812." }] }
]
}To keep only the long-lived part on 12 hours and the session on 30 minutes, OpenAI's guide shows explicit mode with a different lifetime per breakpoint: a request-level "prompt_cache_options": {"mode": "explicit", "ttl": "30m"}, a "prompt_cache_breakpoint": {"mode": "explicit", "ttl": "12h"} on the shared developer instructions, and a breakpoint with no ttl (so 30 minutes) on the session context1. Two placement rules from the guide: top-level instructions cannot hold an explicit breakpoint, so put reusable instructions in an input_text block of a developer message; and the cached prefix must be byte-identical, so keep timestamps, request ids and per-user data after the last breakpoint.
On GPT-5.6 and later, prompt_cache_key is optional and routing is automatic; keys are useful to keep cache accounting separate per customer and to prevent cache-hit probing across users1.
How the alternatives compare
Anthropic. Claude's cache has a 5-minute default and a 1-hour option set with "ttl": "1h" on cache_control. Writes cost 1.25x and 2x the input rate; reads 0.1x, or 0.05x on Opus 5.5 and Sonnet 5.5 and 0.025x on Fable 5.1. Each read refreshes the lifetime at no charge, and a top-level cache_control turns on automatic breakpoint placement4. For steady traffic a 1-hour Anthropic entry that is read at least once an hour can live all day on a single write. Anthropic loses to OpenAI's 12-hour option when gaps between reads exceed an hour; OpenAI's option loses when reads are frequent, because Anthropic's refresh keeps one cheaper write alive indefinitely.
Gemini. Implicit caching is on by default for Gemini 2.5 and later, with a 4,096-token minimum on Gemini 4 Argon, 3.8 Flash and 3.6 Flash5. Explicit caches on generateContent take any TTL ("no minimum or maximum bounds"), default to one hour, and bill storage for as long as the tokens persist; they are not available for Gemini 4 Argon and later, which use implicit caching only6. Gemini 3.8 Flash lists $0.75 input, $0.075 cached and $0.50 per million tokens per hour of storage through 31 December 2026, doubling on 1 January 20277. Twelve hours of storage is $6.00 per million tokens held, so at those rates an explicit cache needs roughly nine reads in the window before it beats sending the prefix uncached. Storage pricing favours short TTLs with dense traffic; OpenAI's 12-hour write favours sparse traffic.
| OpenAI 12-hour | Anthropic 1-hour | Gemini explicit | |
|---|---|---|---|
| Cost to keep a prefix | One 2.5x write per 12 hours | One 2x write, refreshed by reads | Storage per token-hour |
| Loses when | Reads are minutes apart | Reads are more than an hour apart | Reads are few compared with hours stored |
| Control | prompt_cache_options or per breakpoint | cache_control with ttl | Cache object with a TTL or expiry time |
Measure it
Do not judge caching from prompt token counts. OpenAI's usage object separates what you paid for1:
usage.input_tokens_details.cached_tokens: billed cache reads; it excludes tokens charged as writes.usage.input_tokens_details.cache_write_tokens: tokens written in this request.cache_write_tokens_details.ttl_30m_tokensandttl_12h_tokens: the split of those writes by lifetime; they do not overlap and sum tocache_write_tokens.
The healthy pattern for a 12-hour prefix is one request with ttl_12h_tokens near the prefix length, then reads on later requests. Track per workload, per day: write tokens, read tokens, and reads per write. If reads per write falls below two, the 12-hour option is costing you money; if ttl_12h_tokens appears on many requests in the same window, the prefix is changing between them.
On data handling, OpenAI states that prompt caching is compatible with Zero Data Retention, that the cache holds encrypted key-value tensors rather than prompt text with a maximum retention of 24 hours, that the 12-hour setting is not a deletion deadline, and that caches are not shared across organizations or regional processing boundaries1.
Checking cache behaviour through INFRO
INFRO is a control plane in front of the provider accounts you connect; OpenAI bills you directly for every token, cached or not, and INFRO's charge is a separate subscription.
The option reaches OpenAI. On an OpenAI connection, INFRO's POST /v1/responses sends the body as you wrote it, so prompt_cache_options and per-breakpoint settings reach OpenAI unchanged. A request INFRO has to translate for a Chat Completions target cannot carry them. See coding agents.
Reads are visible per request. Each request row and response carries the provider's cached token count (prompt_tokens_details.cached_tokens on chat, input_tokens_details.cached_tokens on Responses), and usage analytics group requests and estimated provider cost by model, key and project. Traffic changes raise a finding when the cached share of prompt tokens on a model drops by 10 percentage points or more, the usual sign that a prefix stopped matching.
What INFRO does not do yet. INFRO's estimate does not price OpenAI cache writes separately: written tokens are estimated at the ordinary input rate, so a 12-hour write, billed at 2.5x, is under-estimated in INFRO's figures. Use OpenAI's own usage fields above, or reconciliation against your provider's cost report, for the true write cost. INFRO's own response cache is a different feature: a hit there never reaches your provider at all.
