
Cut Your Claude API Costs 90%: How cache_control Keeps Long Context Off Your Token Bill
Chris Harper
3 min read
Jul 20, 2026 · 04:05 UTC
Add cache_control: {type: "ephemeral"} to any content block to cache it — cached reads cost 10% of normal input price and return up to 85% faster on the next call.
What you'll be able to do after this:
- Mark system prompts, tool lists, and loaded documents so every follow-up request reuses the cached KV prefix instead of re-processing it
- Choose between 5-minute and 1-hour TTLs depending on whether you're running a conversation session or a batch job
- Use cache diagnostics to verify cache hits and debug unexpected misses without guesswork
For an agent loop with a 10,000-token system prompt that calls Claude 100 times per session: without caching you pay for 1,000,000 input tokens. With caching you pay one cache write (1.25× the base price for 10,000 tokens) + 99 cache reads (0.10× base price for 10,000 tokens each). That's under 115,000 tokens of equivalent cost — roughly 88% less.
Two modes
Automatic (start here): Pass cache_control at the top level of messages.create() and the SDK places the breakpoint at the last cacheable block automatically.
Explicit block-level: Put cache_control directly on individual content blocks when your request has content that changes at different rates — cache the stable 10,000-token system prompt but let the shorter tool definitions update freely.
Walkthrough
import anthropic
client = anthropic.Anthropic()
SYSTEM_PROMPT = """You are a code review assistant.
<codebase>
... (10,000 tokens of repo context) ...
</codebase>"""
# First call: cache write (1.25x price, one-time)
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
system=[{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"} # mark this block
}],
messages=[{"role": "user", "content": "Review auth module for SQL injection risks."}]
)
# Subsequent calls within TTL: cache read (0.10x price, ~85% faster)
response2 = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
system=[{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}
}],
messages=[{"role": "user", "content": "Check for XSS vulnerabilities in the template engine."}]
)
# Verify the cache hit:
print(response2.usage.cache_read_input_tokens) # > 0 means hit
print(response2.usage.cache_creation_input_tokens) # > 0 means write
Pricing
| Cost multiplier | |
|---|---|
| Cache write | 1.25× base input price |
| Cache read | 0.10× base input price |
| Break-even | 2 cache reads per prefix |
TTL options
- 5 minutes (default): refreshed free on each hit; covers most chat sessions and short agent loops
- 1 hour:
"cache_control": {"type": "ephemeral", "ttl": "1h"}at 2× the base write price; better for long document analysis or batch pipelines
Minimum block size
1,024 tokens for Sonnet/Opus; 2,048 for Haiku. Smaller blocks are silently ignored — if you're seeing zero cache hits, check your block sizes first.
Debug misses
The cache diagnostics endpoint (beta) tells you exactly why a specific request missed: wrong block order, content changed, prefix below minimum size, or workspace isolation mismatch (as of Feb 2026, caches are isolated per workspace within an org).
Sources: Prompt caching — Claude Platform Docs, Anthropic Cookbook: Prompt Caching notebook, Cache diagnostics (beta)