Cost Optimization & FinOps

System Prompt Caching ROI: Step-by-Step Calculation

Prompt caching turns a repeated system prompt from full-price input into a 90%-discounted cache read. Here is the arithmetic, start to finish.

Claude 3P 101 · Updated July 2026 · Unofficial guide

If every request your application sends starts with the same system prompt — instructions, policies, few-shot examples — you are paying to process those tokens from scratch on every call. Prompt caching lets the API reuse its work: you pay a one-time premium to write the prefix into a cache, then a steep discount every time it is read back. This article walks through the exact prices, the break-even point, and what the savings look like at real volumes.

The three prices that matter

Caching prices are multipliers on the model's base input price: a 5-minute cache write costs 1.25x base input, a 1-hour cache write costs 2x, and every cache read costs 0.1x. On Claude Opus 4.8, whose base input price is $5 per million tokens, that means:

Token type (Opus 4.8)Price per MTok
Regular input$5.00
5-minute cache write$6.25
1-hour cache write$10.00
Cache read$0.50

Break-even is fast. With the 5-minute duration, one write plus one read costs 1.25x + 0.1x = 1.35x — already cheaper than paying 2x for two uncached passes. The 1-hour duration (2x write) needs at least two reads to pay off. In other words: caching pays for itself on the second request for the 5-minute TTL, the third for the 1-hour TTL.

Placing cache_control

There are two ways to enable caching. The recommended default is automatic caching — a single top-level cache_control field on the request, which places the breakpoint on the last cacheable block and moves it forward as the conversation grows. For explicit control, mark individual content blocks:

from anthropic import AnthropicVertex

client = AnthropicVertex(project_id="my-project", region="global")
resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    system=[{
        "type": "text",
        "text": LONG_SYSTEM_PROMPT,  # policies, examples, schemas
        "cache_control": {"type": "ephemeral"},  # 5-min TTL
    }],
    messages=[{"role": "user", "content": user_question}],
)
print(resp.usage.cache_read_input_tokens)

Two placement rules with cost consequences. First, minimum cacheable length: 1,024 tokens on Opus 4.8, Sonnet 5, Sonnet 4.6, and Haiku 4.5 (512 on Claude Fable 5; 1,024 for Fable 5 on Bedrock). A shorter prefix simply won't cache. Second, caching is a strict prefix match — one changed byte (a timestamp, a user ID, non-deterministic JSON ordering) invalidates everything after it. Keep dynamic content after the breakpoint.

Savings at volume

Take a 2,000-token system prompt on Opus 4.8. Uncached, that prefix costs 2,000 × $5/MTok = $0.01 of input per request. As a cache read it costs 2,000 × $0.50/MTok = $0.001. Assuming steady traffic keeps the 5-minute cache warm (so nearly every request is a hit), the prefix cost per month is roughly:

Requests / monthUncached prefix costCached (mostly hits)Saved
10,000$100~$10~$90
100,000$1,000~$100~$900
1,000,000$10,000~$1,000~$9,000

Each cache miss adds a write at $6.25/MTok ($0.0125 for our 2,000-token prompt), so bursty traffic with long gaps sees smaller savings; the 1-hour TTL ($10/MTok write) can be the better fit there. Scale the prefix up — a 20,000-token tool-and-policy preamble is common in agentic apps — and every figure above multiplies by ten.

Verify with usage fields: every response reports cache_creation_input_tokens, cache_read_input_tokens, and input_tokens. If reads aren't dominating after warm-up, something is silently invalidating your prefix.

Caching stacks with the Batch API's 50% discount and works on all four third-party platforms, with one caveat: Amazon Bedrock supports explicit breakpoints only, not automatic caching.

Choosing the TTL, and pre-warming

Pick the TTL from your traffic's inter-arrival time, not from instinct. If requests reliably arrive within five minutes of each other, the default TTL is strictly cheaper — reads refresh the entry, so a busy cache stays warm indefinitely at the 1.25x write price. If gaps routinely exceed five minutes but stay under an hour (a batch pipeline that fires every 20 minutes, an internal tool with lunchtime lulls), the 1-hour TTL's 2x write price beats paying repeated 1.25x re-writes. For predictable daily jobs, you can pre-warm: a request with max_tokens: 0 writes the cache without generating output — you pay the cache write, no output tokens. One concurrency trap from the official guidance: a cache entry becomes readable only after the first response begins, so firing 50 identical requests in parallel means all 50 pay full write price. For fan-out workloads, send one request first, wait for its first streamed token, then release the rest.

Where to go next

See cache write vs. read economics for a deeper pricing breakdown and cache hit-rate strategy for keeping the hit rate high in production.

Sources