Research-backed calculator guide
OpenAI Cached Input Billing: Read, Write, and Ordinary Input on One Request
Learn how to calculate OpenAI cached input billing when one request contains ordinary input, cache reads, 30-minute writes, and 12-hour writes.
Quick answer
OpenAI cached input billing is a weighted-input calculation, not a second fee added to the ordinary input charge. Start with the request's total input_tokens. Subtract the tokens reported as cached reads and cache writes to find ordinary input. Then multiply each remaining bucket by its own price per million tokens:
ordinary input = input_tokens - cached_tokens - cache_write_tokens
input cost = (ordinary × ordinary-input rate
+ cached reads × cached-input rate
+ 30m writes × 30m-write rate
+ 12h writes × 12h-write rate) / 1,000,000
For a request that reports both 30-minute and 12-hour writes, use cache_write_tokens_details.ttl_30m_tokens and ttl_12h_tokens. Those two write fields sum to cache_write_tokens; do not add cache_write_tokens a second time. OpenAI's prompt-caching guide shows this same ledger approach and says that cached_tokens counts billed reads while excluding tokens charged as writes. [1]
The practical answer to “are cache reads and writes additive?” is no, not in the way many first ledgers assume. A write rate replaces the ordinary-input rate for the written tokens. A read rate replaces it for the cached-read tokens. Output tokens are a separate line item and are not part of the input-token calculation.
The three input buckets on one request
Treat the usage object as a set of billing buckets. input_tokens is the request's total input-token count. It includes the prefix that was read from cache, any prefix written during the request, and content processed at the ordinary rate. The detailed fields tell you how to weight those portions.
Ordinary input is content that is neither a cache read nor a cache write for this request. It uses the model's standard input rate. If a request has 12,000 input tokens, 4,000 cached tokens, and 7,000 cache-write tokens, the ordinary remainder is 1,000 tokens.
Cached input is a prefix successfully read from an existing cache. It uses the model's cached-input rate, which is normally lower than the ordinary rate. It still counts toward the context window and token-per-minute limits; caching changes the price and often latency, not the amount of context the model receives. [1]
Cache-write input is a prefix written into the cache. On models and endpoints that expose write pricing, the write rate replaces ordinary input pricing for those tokens. Current OpenAI pricing pages present ordinary input, cached input, 30-minute write, and 12-hour write as separate per-million-token rates for supported models. [2]
The fields are easy to misread because a multi-turn workflow can create several cache operations across its internal steps. Reconcile one response object at a time, and use the detailed write-lifetime fields when they are available. If a provider or gateway has transformed the response, retain the raw usage payload beside your calculated ledger so you can investigate any mismatch later.
Formula for OpenAI cached input billing
Use these symbols:
I= totalinput_tokens.R=cached_tokens, the billed cache-read tokens.W30= 30-minute cache-write tokens.W12= 12-hour cache-write tokens.P= ordinary input price per million tokens.C= cached-input price per million tokens.P30= 30-minute write price per million tokens.P12= 12-hour write price per million tokens.
First calculate the ordinary remainder:
ordinary = I - R - W30 - W12
Then calculate input cost:
input cost = (ordinary × P
+ R × C
+ W30 × P30
+ W12 × P12) / 1,000,000
If the response exposes only cache_write_tokens and not a lifetime split, use the applicable write rate for the endpoint or model. If the API reports cache_write_tokens_details, use each component exactly once. OpenAI's documented example uses an input total of 12,000, 4,000 cached reads, and 7,000 writes, leaving 1,000 ordinary tokens; it explicitly warns not to add the aggregate write count after pricing its components. [1]
A useful validation check is that the input buckets should reconcile to the total: ordinary + cached reads + write components = input_tokens. If the result is negative, stop and inspect the raw response rather than forcing a zero. It may indicate that you mixed fields from different API objects, combined usage across internal tool turns, or encountered a provider reporting issue. The OpenAI community has documented an earlier GPT-5.6 reporting bug in which cached_tokens + cache_write_tokens exceeded the request's apparent prompt total; OpenAI later said the issue had been fixed and that affected requests would be reviewed. Treat that discussion as a warning to verify raw usage, not as a pricing source.
Worked cost example
Assume a standard, short-context gpt-5.6-sol request checked on November 2, 2026. The example uses the rates shown on OpenAI's pricing page on that date: $4.00 per million ordinary input tokens, $0.40 per million cached-input tokens, $5.00 per million 30-minute writes, and $10.00 per million 12-hour writes. These are vendor-listed rates, not an estimate. They exclude output cost, batch or fast-mode adjustments, regional processing uplifts, taxes, and any later price change. [2]
The request reports 12,000 input tokens. Of those, 4,000 are cached reads, 3,000 are written for 30 minutes, and 4,000 are written for 12 hours. The remaining 1,000 are ordinary input. The following table makes every assumption visible.
| Step | Token bucket or calculation | Tokens | Rate per 1M tokens | Cost |
|---|---|---|---|---|
| 1 | Total input reported by API | 12,000 | — | — |
| 2 | Cached reads | 4,000 | $0.40 | $0.00160 |
| 3 | 30-minute writes | 3,000 | $5.00 | $0.01500 |
| 4 | 12-hour writes | 4,000 | $10.00 | $0.04000 |
| 5 | Ordinary remainder: 12,000 − 4,000 − 3,000 − 4,000 | 1,000 | $4.00 | $0.00400 |
| 6 | Input total | 12,000 | — | $0.06060 |
The input total is therefore $0.06060. If the model generated 2,000 output tokens at the listed $20.00 per million output rate, output would add $0.04000, producing a request total of $0.10060 before any other billable tool or service charges. The output line is intentionally separate: caching does not discount output, and reasoning tokens, where applicable, are accounted for under output usage rather than folded into the input ledger.
Notice what the example does not do. It does not charge 12,000 ordinary input tokens and then add a cache-write surcharge. It prices each input token once. It also does not calculate 4,000 + 3,000 + 4,000 as an extra token total; those are classifications of the 12,000 input tokens.
For a quick sensitivity check, suppose the same 12,000-token request has no cache reads or writes. Its input cost would be 12,000 × $4 / 1,000,000 = $0.04800. In this particular assumption set, the 12-hour writes make the cached version more expensive than ordinary processing for that one request. Caching becomes economically attractive when the written prefix is reused enough times for lower-priced reads to outweigh the write premium. That break-even depends on the model's actual rates, write lifetime, prefix size, and the number and timing of later hits.
Run your scenario
Turn this framework into an editable estimate.
Use dated, source-linked assumptions and see cost per request, successful task and month.
How to build a prompt cache ledger from usage JSON
Store the raw response usage and a normalized row for each request. At minimum, record the request ID, model, API mode, service tier, timestamp, input_tokens, cached_tokens, cache_write_tokens, write-lifetime details, output tokens, and the rate-card version used. A rate-card date matters because vendor pricing can change independently of your token counts.
For each row, calculate ordinary_input_tokens. Do not infer it from a rounded percentage or from a dashboard's cache-hit rate. Use the integer fields in the response. If the write details are present, set cache_write_tokens equal to the sum of its lifetime components and assert that equality. Then assert that ordinary, reads, and writes sum to total input. Keep the calculation in decimal currency until the final presentation so small API calls do not disappear through early rounding.
A cache-hit rate is useful for operations, but it is not a cost rate. A simple operational ratio is cached_tokens / input_tokens. It can show whether a stable prefix is being reused, but it does not tell you whether the workload is profitable to cache. A workload with a high hit rate can still be expensive if it repeatedly incurs a large 12-hour write price. Conversely, a workload with a modest hit rate can save money when the reusable prefix is large and the cached-input rate is far below ordinary input.
For a monthly estimate, aggregate by the same pricing dimensions. Do not mix standard and fast processing, short and long context tiers, or different models in one rate column. Sum token buckets first, apply the matching rates, and then add output and other billable components. The model pricing comparison page can help organize a multi-model rate sheet, while the LLM cost calculator is useful for scenario-level comparisons. When actual provider usage arrives, reconcile it with the AI API invoice reconciliation calculator rather than treating a forecast as an invoice.
Prompt design choices that affect cost
Place stable instructions, schemas, and reference material before changing user content. This increases the chance that the reusable prefix remains identical. OpenAI's guide describes minimum cacheable lengths and explicit breakpoints for supported models; Microsoft’s Azure OpenAI documentation likewise describes a 1,024-token minimum and shows cached_tokens and cache_write_tokens in usage for relevant deployments. [1] [3]
If the changing tail is not worth writing, explicit-only caching can keep it at the ordinary input rate instead of creating a write for content unlikely to be reused. This is a cost-control decision, not a promise that every request will hit the cache. Cache availability depends on model, endpoint, prefix identity, lifetime, routing, and traffic shape. Measure actual reads and writes after changing prompt structure.
For Azure-hosted OpenAI models, do not assume every OpenAI API behavior maps one-for-one to every deployment type. Azure's documentation distinguishes Standard pay-as-you-go from Provisioned Throughput and notes that some breakpoint and write fields are deployment-specific. [3] If your invoice comes from Azure, use the Azure rate card and deployment semantics for the final reconciliation.
Common mistakes to avoid
Adding the write count twice. If ttl_30m_tokens and ttl_12h_tokens already sum to cache_write_tokens, price the two components and stop. Adding the aggregate again overstates cost.
Using cached-token count as the discount percentage. Cached tokens are token units. Their dollar value comes from the model's cached-input rate, not from a universal percentage.
Subtracting output tokens from input. Output is a separate meter. Use only input and input-detail fields to derive ordinary input.
Using today's rate for last month's invoice. Preserve the applicable rate card and service tier with the usage row. The pricing page is time-sensitive, and its displayed rates are not a guarantee for future requests. [2]
Treating a cache hit as guaranteed. A stable prefix improves the opportunity for reuse, but it does not guarantee a hit on every call. Use observed cached_tokens and write counts in your forecast.
FAQ
Is cache-write pricing an extra surcharge on top of ordinary input?
No. For the token portion classified as a cache write, use the applicable cache-write rate instead of the ordinary-input rate. The write rate is often higher than ordinary input because it prices creating cache state, but that does not mean you add both rates to the same tokens. If a request has 30-minute and 12-hour writes, price each write bucket once. [1]
Can one request contain ordinary input, cache reads, and cache writes?
Yes. A single request can have an ordinary tail, read an existing cached prefix, and write another eligible prefix or coverage tier. That is why a single aggregate input number is insufficient for reconciliation. Use the detailed usage fields and derive the ordinary remainder after identifying the read and write buckets.
What does cached_tokens mean for billing?
It is the number of input tokens billed at the model's cached-input rate for that usage object. It is not a separate output meter and it does not increase the context window. The exact cache behavior depends on the model and endpoint, so use the current provider documentation and the response's actual fields.
How do I calculate a request when only cache_write_tokens is available?
Use ordinary = input_tokens − cached_tokens − cache_write_tokens, then price the ordinary, cached, and write portions with their applicable rates. If the endpoint supports multiple write lifetimes but does not return the split, obtain the correct write rate from its rate card or billing export. Do not invent a split from a rounded dashboard metric.
Why can a cached request cost more than an uncached request?
A first write can carry a premium, especially for a longer retention tier. Compare the one-time or periodic write cost with the savings from later cache reads. The break-even number of hits is workload-specific. A prefix that is rarely reused may not justify an expensive write, while a stable prefix reused across many requests may repay it quickly.
Does prompt caching reduce output-token charges or token limits?
No. Prompt caching changes the treatment of eligible input tokens. Output tokens remain separately priced, and cached input still occupies context and counts toward relevant token limits. Budget input and output independently, then include tool or service charges where applicable. [1]
Primary sources checked
Pricing and product behavior can change. These sources support the time-sensitive claims in this guide; verify current provider terms before committing spend.