Prompt caching: cutting cost on a repeated prefix

Cache reads and cache writes are their own billing buckets with their own rates. Which means the saving is real, and so is the write you paid for.

Four buckets, not one input number

Every billed request is split into four disjoint buckets: fresh input, output, cache reads, and cache creation. Each is priced from its own per-million-token rate and the model's multiplier is then applied to the total, so a cached prefix genuinely stops being charged at the fresh-input rate.

On claude-sonnet-5 the official rates are $3 per million input and $15 output, with cache reads at $0.30 and cache creation at $3.75. Reading from cache costs a tenth of fresh input; writing to it costs about a quarter more than sending the text plainly. At the model's 0.1× multiplier, all four scale together.

The write is the part people forget. A prefix has to be paid into the cache before it can be read back cheaply, so caching a prefix you use once is strictly worse than not caching it. The break-even is roughly the second read.

A cache breakpoint on a long system prompt. Run it twice — the second call reports cache_read_input_tokens.
curl https://token-share.app/v1/messages \
  -H "x-api-key: $TOKEN_SHARE_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 512,
    "system": [
      {
        "type": "text",
        "text": "You are reviewing a codebase. Style guide follows. ...(a long, stable prefix)...",
        "cache_control": {"type": "ephemeral"}
      }
    ],
    "messages": [{"role": "user", "content": "Review the diff I paste next."}]
  }' | python3 -c 'import json,sys; print(json.load(sys.stdin)["usage"])'

Where the breakpoint has to go

Cache reuse is prefix-based, so the cached span has to sit at the front and has to be byte-identical between calls. A timestamp, a request id, or a per-user greeting placed above the stable text moves everything below it and turns every call into a cache miss you still paid to write.

On /v1/messages, mark the boundary with cache_control on the last block you want covered — typically the system prompt or a large document block. The directive is forwarded with the request rather than rewritten, so what the upstream honours is what you sent.

Order your prompt so the stable part is genuinely stable: system instructions and reference material first, then whatever changes per turn. That ordering is the whole technique; the cache_control marker only says where the stable part ends.

Not every model prices a cache write

The Claude ids and the newer GPT-5.6 ids declare both a cache-read and a cache-creation rate. Several others — gpt-5.5, gpt-5.4, gpt-5.4-mini, the Grok ids and the Gemini ids — declare a cache-read rate but no cache-creation rate, and for those the write falls back to the model's full input price.

That changes the arithmetic rather than the technique. On gemini-3-flash, official input is $0.50 per million and cache reads are $0.05 — a tenth — while a write costs the same $0.50 as sending the text fresh. The write is cheaper in relative terms than on a model that charges a premium for it, but the read discount is what you are buying either way.

Cached input is also reported differently by different upstreams: some count cached tokens inside the input total, others report them beside it. The proxy normalizes those into the four disjoint buckets before pricing, so what you are billed for does not depend on which convention the provider used. Read the usage object on a real call for the model you plan to run — it is the only figure that reflects your actual prompt.

Common questions

How do I tell whether a cache hit actually happened?
Read the usage object on the response. A hit reports a non-zero cache read count; the call that populated the cache reports a cache creation count instead. If you see creation on every call, the prefix is not byte-identical between them — something above it is changing.
Does caching help if I am just pasting a big repository into every request?
Only if that content is identical every time and you send it often enough to amortise the write. Caching lowers the price of a repeated prefix; it does not make a large context cheap, and it does nothing for content that changes between calls. If the repository text is stable across a long session, the saving is real — if you are pasting a fresh diff each turn, it is not.
Does caching work on the OpenAI-shaped routes and on stable lanes?
Cache directives are carried through on all of them, and cached input is billed from its own bucket regardless of the route you called. Each id has its own cache rates in the catalog, including the stable-* lanes, so price the workload against the specific id rather than assuming one model's ratio carries to another.