Search across all documentation pages
A quick reference for the two cache TTL (time-to-live) windows Claude supports, what each one costs relative to a normal input token, and how to select one in the cache_control block.
usage.cache_read_input_tokens and usage.cache_creation_input_tokens on real responses to validate your assumptions against actual traffic.| TTL | cache_control value | Cache lifetime | Cache write cost | Best fit |
|---|---|---|---|---|
| Default (5 minutes) | {"type": "ephemeral"} | Refreshed on each hit; expires 5 minutes after the last access | Base cache-write multiplier over a normal input token | Interactive sessions, chat UIs, request bursts within a few minutes of each other |
| Extended (1 hour) | {"type": "ephemeral", "ttl": "1h"} | Refreshed on each hit; expires 1 hour after the last access | Higher cache-write multiplier than the 5-minute default | Long-running agent sessions, batch jobs spread over an hour, infrequent-but-recurring workloads |
cache_read_input_tokens) is always billed at a lower rate than a normal input token, regardless of which TTL wrote the entry.cache_creation_input_tokens) costs more than a normal input token on both TTLs - the 1-hour TTL's write multiplier is higher than the 5-minute TTL's write multiplier, since you're paying for a longer-lived guarantee.import anthropic
client = anthropic.Anthropic()
# 5-minute default TTL - omit "ttl" entirely, or set it explicitly.
system_5m = [
{
"type": "text",
"text": "You are Acme Corp's support assistant." * 50,
"cache_control": {"type": "ephemeral"},
usage.cache_read_input_tokens and usage.cache_creation_input_tokens in production and revisit the TTL choice based on observed hit rates rather than a guess.response = client.messages.create(
model="claude-sonnet-5",
max_tokens=200,
system=system_1h,
messages=[{"role": "user", "content": "What's your refund window?"}],
)
usage = response.usage
cache_creation_input_tokens with zero cache_read_input_tokens means this call wrote the cache for the first time (or after it expired).cache_read_input_tokens means the request hit an existing entry under whichever TTL wrote it.A default 5-minute window and an extended 1-hour window, both set via the cache_control block on cacheable content.
Add "ttl": "1h" inside the cache_control dict: {"type": "ephemeral", "ttl": "1h"}. Omitting ttl uses the 5-minute default.
No - both TTLs are ephemeral and refresh on every cache hit, so the expiration clock resets each time the entry is read, not just when it was written.
The 5-minute default has a lower cache-write cost multiplier than the 1-hour extended TTL. Reads are billed the same lower rate regardless of which TTL wrote the entry.
No - default to the 5-minute TTL unless you have a concrete reason (session gaps longer than a few minutes) to pay the higher write cost for the 1-hour window.
At platform.claude.com/docs. This page deliberately describes cost behavior qualitatively because exact multipliers change over time and vary by model.
The TTL is set per cache_control block, so different breakpoints in the same request can use different TTLs if your workload genuinely needs that split.
The response doesn't echo it back directly - you already know it, since you set ttl in the request. Track it on your own side alongside the usage fields if you need it in logs.
A cache read also refreshes the expiration - that's what "ephemeral, refreshed on hit" means. A steady stream of hits within the window keeps the entry alive well past its original TTL.
Yes, cache reads are billed at a lower rate than normal input tokens on both TTLs; the TTL choice affects the write cost, not the read discount.
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the official
anthropicPython SDK (latest 0.x release). Model names, SDK versions, and pricing move quickly - verify current specifics at platform.claude.com/docs before relying on them.