Anthropic Prompt Caching Claude API 9 min read

Anthropic Prompt Caching Guide 2025: Reduce Claude API Costs 90%

Prompt caching is Anthropic's most impactful cost-reduction feature for the Claude API. By marking large, reused context blocks with a single JSON field, you can cut cache-read costs by 90% and dramatically reduce latency on every repeated call — perfect for RAG pipelines, agents with many tools, and long system prompts.

What Is Prompt Caching?

Prompt caching is a Claude API feature that stores a prefix of your prompt on Anthropic's infrastructure. On the first request, Claude processes the full prompt and writes a cached snapshot at a 25% price premium over the normal input rate. Every subsequent request that reuses the same prefix pays only the cache read price — 90% less than full input processing.

The cache TTL is 5 minutes, refreshed on every cache hit. An active agent loop or multi-turn chat can keep the cache warm indefinitely. If no request reuses the cache within 5 minutes, the block expires and the next call writes a fresh cache entry.

Use cases that benefit most: RAG with the same large document context, system prompts longer than ~1,000 tokens, tool definitions for agents with 20+ functions, few-shot example banks, and coding assistants that include large codebase snippets in every call.

Minimum Cache Block Sizes

Prompt caching only activates when the content being cached meets the minimum token threshold for the model being used. Content below the threshold is processed and billed at the normal input rate — no error is raised, the cache control field is simply ignored.

Model Min cache tokens Notes
Claude Haiku 4.5 2,048 tokens Fastest + cheapest model
Claude Sonnet 4.6 1,024 tokens Best cost/quality balance
Claude Opus 4.8 1,024 tokens Most capable model

A typical English sentence is ~15-20 tokens. A 1,024-token system prompt is roughly 750-800 words — a detailed coding assistant persona or a multi-step chain-of-thought instruction block easily exceeds this threshold.

How to Enable Prompt Caching

Add "cache_control": {"type": "ephemeral"} to any content block you want to cache. The field goes directly inside the content block object — system content, user messages, and tool result content all support it.

System prompt caching — Python SDK

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": "You are an expert Python engineer. " * 200,  # ~1,200 tokens
            "cache_control": {"type": "ephemeral"}
        }
    ],
    messages=[
        {"role": "user", "content": "Write a binary search function."}
    ]
)

# Check cache usage in response metadata
usage = response.usage
print(f"Cache write tokens: {usage.cache_creation_input_tokens}")
print(f"Cache read tokens:  {usage.cache_read_input_tokens}")
print(f"Input tokens:       {usage.input_tokens}")

The response's usage object surfaces two new fields: cache_creation_input_tokens (billed at 1.25x) and cache_read_input_tokens (billed at 0.10x). On the first call, you'll see a cache write. On subsequent calls within 5 minutes, you'll see a cache read.

Caching System Prompts

System prompts are the most common caching target. A detailed assistant persona, long instruction set, or domain knowledge block that stays constant across all user turns is ideal — mark the last content block of the system array with cache_control:

Caching a multi-block system prompt

system = [
    {
        "type": "text",
        "text": "You are a senior software engineer specializing in distributed systems.",
    },
    {
        "type": "text",
        "text": LARGE_CODING_STYLE_GUIDE,  # ~3,000 tokens of style rules
        "cache_control": {"type": "ephemeral"}
    }
]

# First request: cache_creation_input_tokens ~= 3,200 (billed at 1.25x)
# Second request: cache_read_input_tokens ~= 3,200 (billed at 0.10x)
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=2048,
    system=system,
    messages=[{"role": "user", "content": user_question}]
)

Only the last content block marked with cache_control anchors the cache boundary. Everything before it in the array is included in the cached prefix — you do not need to mark every block individually.

Caching Large Documents

For RAG pipelines that fetch a long document once and then answer multiple questions about it, cache the document in the user message. This pattern is especially effective when you want Claude to answer several questions about the same source without re-uploading tens of thousands of tokens on every turn:

Document caching for Q&A pipeline

def ask_about_document(document_text: str, question: str):
    return client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": f"Here is the document:\n\n{document_text}",
                        "cache_control": {"type": "ephemeral"}
                    },
                    {
                        "type": "text",
                        "text": question  # Fresh each call — not cached
                    }
                ]
            }
        ]
    )

# First question writes the cache
r1 = ask_about_document(LONG_REPORT, "What is the executive summary?")

# Second question reads from cache — 90% cheaper on the document tokens
r2 = ask_about_document(LONG_REPORT, "What are the key risks mentioned?")

Caching Tool Definitions

Agents that use function calling with many tools pay the full input cost for all tool definitions on every API call. With 20+ tool definitions (each with name, description, and JSON schema), this can easily add 3,000-5,000 tokens per call. Cache the tools array to eliminate this overhead:

Caching tool definitions for an agent

tools = [
    {
        "name": "search_web",
        "description": "Search the internet for current information.",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "Search query"}
            },
            "required": ["query"]
        }
    },
    # ... 20+ more tool definitions ...
    {
        "name": "send_email",
        "description": "Send an email to a recipient.",
        "input_schema": {
            "type": "object",
            "properties": {
                "to": {"type": "string"},
                "subject": {"type": "string"},
                "body": {"type": "string"}
            },
            "required": ["to", "subject", "body"]
        },
        # Mark the last tool to cache everything before it
        "cache_control": {"type": "ephemeral"}
    }
]

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=4096,
    tools=tools,
    messages=[{"role": "user", "content": "Book a flight and email the confirmation."}]
)

Place cache_control on the last tool in the array. All tools before it are included in the cached prefix automatically. The agent loop then reads the cached tool definitions on every subsequent turn.

Multi-Turn Conversation Caching

In long conversations, earlier turns become a stable prefix that can be cached. Mark the last message of the already-processed history with cache_control. Only the newest user message needs fresh processing:

Caching conversation history

conversation_history = [
    {"role": "user",      "content": "Let's analyze this 50-page report."},
    {"role": "assistant", "content": "Sure, I'll start with the executive summary..."},
    {"role": "user",      "content": "Now focus on chapter 3."},
    {
        "role": "assistant",
        "content": [
            {
                "type": "text",
                "text": "Chapter 3 covers the financial projections...",
                "cache_control": {"type": "ephemeral"}  # Cache everything up to here
            }
        ]
    }
]

# New message is NOT in the cache — only fresh token cost
conversation_history.append(
    {"role": "user", "content": "What are the risks in chapter 4?"}
)

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=conversation_history
)

This pattern keeps multi-turn costs nearly flat as conversation history grows. Only new turns — not the entire accumulated history — incur full input pricing.

Pricing & Savings Calculator

Prompt caching pricing is relative to each model's base input token price. The cache write premium pays for itself after just two reuses:

Model Normal input Cache write (1.25x) Cache read (0.10x)
Claude Haiku 4.5 $0.80 / MTok $1.00 / MTok $0.08 / MTok
Claude Sonnet 4.6 $3.00 / MTok $3.75 / MTok $0.30 / MTok
Claude Opus 4.8 $15.00 / MTok $18.75 / MTok $1.50 / MTok

Example — RAG app with 10K token context on Claude Sonnet 4.6:

# 10,000 token document context, 100 questions per document

# WITHOUT caching
# 100 calls * 10,000 tokens * $3.00/MTok = $3.00 per document

# WITH caching (first call writes, 99 calls read)
# Write:  1 call  *  10,000 tokens * $3.75/MTok = $0.0375
# Reads: 99 calls *  10,000 tokens * $0.30/MTok = $0.297
# Total: $0.3345 per document

# Savings: $3.00 - $0.3345 = $2.67 saved per document (89% reduction)

At 1,000 documents per day, caching saves over $2,600/day on Sonnet 4.6 for this workload. The break-even point is just 2 cache reads per write.

Caching Helps With Cost — But Not Outages

Caching helps with cost — but when Anthropic's API itself has an outage, there's nothing to cache. Prismix monitors Claude's real-time status.

Monitor Anthropic Status →