◉CLAUDE LABJP
●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…
Articles/API & SDK
⬡ API & SDK/2026-04-28Intermediate

Diagnosing Claude API Prompt Cache Misses — How to Read the usage Field

If your Claude API prompt cache isn't reducing your bill, the usage field is where to start. This guide walks through the five most common reasons cache_read_input_tokens stays at zero and how to fix each one.

claude-api83prompt-caching15troubleshooting92cost-optimization31anthropic12

✦ Premium Article

"I added cache_control last week, but my invoice didn't shrink at all" — this is the single most common message I get from people who just tried Claude's prompt caching. I went through the same thing the first time I shipped it: three days of zero hits before I noticed the cache hadn't been working at all.

The good news is that the failure modes are surprisingly limited, and every diagnosis starts in the same place: the usage object that the API returns on every response. This guide walks through the five misses I run into most often, in the order I check them.

Start with the usage field

Every Claude API response includes a usage object. When you have prompt caching enabled, two extra fields appear there.

import anthropic
 
client = anthropic.Anthropic()
 
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": "You are an experienced technical writer." * 200,  # ~2,000 tokens
            "cache_control": {"type": "ephemeral"},
        }
    ],
    messages=[{"role": "user", "content": "Hello"}],
)
 
print(response.usage)
# Usage(
#   input_tokens=8,
#   cache_creation_input_tokens=2103,
#   cache_read_input_tokens=0,
#   output_tokens=42
# )

Three numbers matter here.

  • input_tokens: tokens that bypass the cache and get re-read every request
  • cache_creation_input_tokens: tokens written to the cache on this request (billed at 1.25× standard for the 5-minute TTL, 2× for the 1-hour TTL — but only on first write)
  • cache_read_input_tokens: tokens served from the cache (billed at 0.1× standard)

A working cache means: from the second request onward, cache_read_input_tokens is positive and cache_creation_input_tokens drops toward zero. If you keep firing identical prompts and these numbers never shift, something is wrong.

Cause #1: The prefix is below the minimum token count

Claude enforces a minimum number of tokens for a prefix to be eligible for caching. As of April 2026:

  • Claude Sonnet 4.6 / Claude Opus 4.6: 1,024 tokens
  • Claude Haiku 4.5 family: 2,048 tokens

If your cached prefix is shorter than that, the server quietly skips caching. cache_creation_input_tokens stays at zero, input_tokens keeps climbing, and you wonder why nothing is happening.

This is the trap I fell into first — a 600-token system prompt with cache_control attached and lots of confused log diving. Run your prefix through the token counter before assuming the cache is broken. If you're under the threshold, your next move isn't caching; it's compressing the prompt itself.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦A five-cause diagnostic order for reading cache_read_input_tokens in the usage field
✦Real numbers from a 1,000-image batch — input_tokens from 3,210 to 12, TTFT from 1.42s to 0.83s
✦A decision table for choosing the 5-minute vs 1-hour TTL and holding a 10-to-1 read-to-write ratio
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

⬡ API & SDK2026-04-26
How I Cut My Claude API Bill in Half With Prompt Caching
Done right, Anthropic's prompt caching can roughly halve your monthly API spend on workloads with long, repeated system prompts. Here is the design playbook I use after six months in production, including the arithmetic that links hit rate to the bill and the break-even points (about 22% on the 5-minute TTL, 53% on the 1-hour TTL).
⬡ API & SDK2026-09-07
A 75% cheaper cache read moved one bill by 29% and another by 2.8%
Fable 5.1 and Mythos 5.1 changed the cache read multiplier from 0.1 to 0.025. Here is how to estimate your own saving from your token mix, and how to fix code that hard-codes the multiplier.
⬡ API & SDK2026-05-25
A Two-Tier Setup — Haiku 4.5 Orchestrator with Opus 4.6 Worker for Balancing Cost and Quality
An indie developer's two-tier setup — Haiku 4.5 as orchestrator, Opus 4.6 as worker — costed line by line against published rates, plus the price increase I planned around that never arrived and the tokenizer split that quietly moves every token-denominated threshold.