PREDICTIVE TREND INSIGHT
Optimizing prompt caching on Claude Sonnet 5 for B2B analytics Illustration

Optimizing prompt caching on Claude Sonnet 5 for B2B analytics

Direct Summary:

Prompt caching on Claude lets you pay full price once to cache a large, repeated block of context (a system prompt, a schema, reference documents) and then read it back at roughly a tenth of the input cost on every subsequent request — a strong fit for B2B analytics tools where every analyst query re-sends the same large dataset description or business context. Mark the reusable block with a cache_control breakpoint; the cache is a prefix match, so anything that changes even one byte earlier in the prompt invalidates everything cached after it.

"A goal without a plan is just a wish."

— Antoine de Saint-Exupery

Key Insights

  • It's a prefix match, not a smart cache: caching works on exact byte sequences from the start of the prompt. A timestamp or per-request ID anywhere before your cached block invalidates it — keep volatile content after the cache breakpoint, not before it.
  • Writes cost more, reads cost much less: writing to the cache costs roughly 1.25x the normal input price (2x for a 1-hour TTL instead of the default 5-minute one); reading from it costs roughly 0.1x. The economics favor caching anything reused more than once or twice.
  • Verify it's actually working: the API response's usage block reports cache_read_input_tokens separately from full-price input_tokens — if reads stay at zero across repeated requests, something in your "stable" prefix is silently changing between calls.

A B2B analytics assistant is close to the textbook case for prompt caching: the same large context — a data dictionary, last quarter's KPI definitions, a company's reporting conventions — gets sent on every single query, with only the analyst's actual question changing. Without caching, you pay full input price for that context on every request. With caching, you pay it once, then a fraction of that on every request afterward, for as long as the cache stays warm.

Setting it up correctly

1. Put the stable content first, the changing question last. Caching works on a prefix — order the request so the large, reused context comes before the analyst's specific query, and mark the end of the reused block with a cache breakpoint.

2. Use a real, current model. "Claude 3.5 Sonnet" was retired in October 2025 — the current mid-tier model is Claude Sonnet 5 (claude-sonnet-5), and prompt caching works the same way across it and the current Opus and Haiku tiers.

3. Check the usage numbers, not just your intuition. After a few requests, look at cache_read_input_tokens in the response. If it's zero, something in the "stable" part of your prompt is actually changing between calls (a generated timestamp, a re-serialized JSON blob with unstable key order) and silently busting the cache every time.

cached_analytics_query.py
# Caching a large, reused analytics context across many analyst questions
import anthropic

client = anthropic.Anthropic()

# DATASET_CONTEXT is the large, stable block (schema, KPI defs, conventions) -
# identical on every call. The analyst's question is the only thing that varies.
response = client.messages.create(
    model="claude-sonnet-5",
    max_tokens=1024,
    system=[{
        "type": "text",
        "text": DATASET_CONTEXT,
        "cache_control": {"type": "ephemeral"}  # marks the end of the cached prefix
    }],
    messages=[{"role": "user", "content": analyst_question}],
)

print(response.usage.cache_read_input_tokens)      # served from cache, ~0.1x cost
print(response.usage.cache_creation_input_tokens)  # written to cache this call, ~1.25x cost
print(response.usage.input_tokens)                 # uncached remainder, full price
Token type Relative cost When it applies
Cache write ~1.25x base input price (5-min TTL) / ~2x (1-hour TTL) The first request that writes the cached block
Cache read ~0.1x base input price Every subsequent request that reuses the same prefix

For a B2B analytics tool fielding dozens of questions against the same underlying context, the arithmetic is straightforward: the break-even point is around two requests for the default 5-minute cache, and around three for the longer 1-hour option. Past that, every additional analyst question against the same context is a meaningfully cheaper and faster call than sending the full context from scratch each time.

Practical Challenge

Take a prompt you're already sending repeatedly with the same large context, add a cache_control breakpoint after the stable part, and run it three times in a row. Check whether cache_read_input_tokens shows up nonzero on the second and third calls.

Concept Check

You add a cache_control breakpoint but cache_read_input_tokens stays at zero across repeated requests. What's the most likely cause?
Correct! Caching is an exact prefix match — any byte-level difference in the "stable" portion of the prompt, even something as small as a regenerated timestamp, invalidates the cache for every request.
Incorrect. Try again! Hint: caching is byte-exact — look for anything that silently varies between otherwise-identical requests.

Sources & Further Reading

Previous Guide Dashboard Next Guide