Cache Long Context

Su Suriya Ravichandran Updated 10 Nov 2026
7 min read ·Lesson 127 of 200

Asking Many Questions About One Document

A common pattern is to load a large document, such as a policy manual, a codebase summary, a research paper, or a contract, and then ask many questions about it. Without caching, every question sends the whole document again, and Claude processes it from the beginning each time. For a 100-page document asked about 20 times, that means paying for 100 pages 20 times.

With caching, the document is written to the cache once, and each later question reads it at a fraction of the price. The questions themselves stay small and cheap, which is where the savings come from.

question 1: [ document (written to cache) | question 1 ]
question 2: [ document (read from cache)  | question 2 ]
question 3: [ document (read from cache)  | question 3 ]

Caching is especially valuable for documents, because a document is usually large, unchanging, and asked about many times, which are the three properties that make a prefix worth caching.


Marking a Document Block

Documents are content blocks, and they can be cached like any other block. Place the cache_control marker on the document block itself, after the document and before the question:

messages = [{"role": "user", "content": [
    {
        "type": "document",
        "title": "Employee Handbook 2026",
        "source": {"type": "text", "media_type": "text/plain", "data": HANDBOOK_TEXT},
        "cache_control": {"type": "ephemeral"},      # cache everything up to and including the document
    },
    {"type": "text", "text": question},               # not cached: changes with each question
]}]

The question comes after the marker, so it is outside the cached prefix. The document is inside it.

According to the documentation, the top-level document blocks that serve as sources can be cached. Sub-content, such as individual citations, cannot be cached directly, so mark the document, not the citation.


Keep the Document Stable

The whole document must be identical across the questions that share it. Practical details matter:

  • Load the text once, and reuse the same string for every question.
  • Do not add per-question instructions to the document block. Instructions belong in the question block, after the marker.
  • Keep the document before any other changing content in the same message.

If you ask several questions in one request, they share the document's cache entry only when the document is the prefix. Questions that change the document itself produce a new entry (Lesson 127).


Practical Example: Several Questions, One Cached Document

This example builds a long handbook, asks three questions about it, and reports the cache fields for each. The first question writes the document, and the next two read it.

"""long_context.py: cache one long document and ask several questions about it."""

from anthropic import Anthropic

client = Anthropic()
MODEL = "claude-opus-5-5"

# A long handbook built from numbered sections, so it is clearly above the minimum length
HANDBOOK_TEXT = "\n\n".join(
    f"Section {n}: Leave policy. Employees who complete {n + 1} months of service may request "
    f"{n + 4} days of paid leave. Requests must be submitted at least {n} weeks in advance, "
    f"through the HR portal, and approved by the line manager."
    for n in range(1, 151)
)

QUESTIONS = [
    "How many days of paid leave can an employee with 3 months of service request?",
    "How far in advance must a leave request be submitted in Section 10?",
    "Who approves leave requests?",
]


def ask(question: str) -> None:
    message = client.messages.create(
        model=MODEL,
        max_tokens=300,
        messages=[{"role": "user", "content": [
            {
                "type": "document",
                "title": "Employee Handbook 2026",
                "source": {"type": "text", "media_type": "text/plain", "data": HANDBOOK_TEXT},
                "cache_control": {"type": "ephemeral"},
            },
            {"type": "text", "text": question},
        ]}],
    )
    usage = message.usage
    answer = "".join(b.text for b in message.content if b.type == "text").strip()
    print(f"Q: {question}")
    print(f"   written={usage.cache_creation_input_tokens} read={usage.cache_read_input_tokens} "
          f"uncached={usage.input_tokens}")
    print(f"A: {answer[:120]}\n")


if __name__ == "__main__":
    for question in QUESTIONS:
        ask(question)

Expected output (the answers and token counts vary):

Q: How many days of paid leave can an employee with 3 months of service request?
   written=<large number> read=0 uncached=<small number>
A: ...

Q: How far in advance must a leave request be submitted in Section 10?
   written=0 read=<the same large number> uncached=<small number>
A: ...

Q: Who approves leave requests?
   written=0 read=<the same large number> uncached=<small number>
A: The line manager approves leave requests...

How It Works

  1. HANDBOOK_TEXT is built once, and is identical for every question, so the document forms the same prefix each time.
  2. The document block carries the marker. Everything up to and including the document is cached, and the question after it is processed normally.
  3. The first question writes the document, so its cache_creation_input_tokens is large.
  4. The next questions read it, so cache_read_input_tokens is large, while input_tokens stays small, since only the question is new.
  5. The title helps Claude refer to the document by name in its answers, and it does not change the cache behavior for the questions that follow.

Note: the first request is also the most expensive, because it pays the write premium. The savings depend on asking enough questions to pay that premium back. Lesson 126 calculates the break-even point.


Common Mistakes

Putting the Question Before the Document

What happens: the question is part of the prefix, so each question creates a new entry, and no reads happen.

Fix: place the document first, the marker on the document, and the question after it.

Adding Per-Question Changes to the Document

What happens: small edits, such as a new heading or a changed date, produce a different document for each question.

Fix: keep the document exactly the same, and put instructions in the question.

Expecting Parallel Questions to Share Immediately

What happens: several requests sent at the same moment all write the entry, because none of them finished first.

Fix: send the first request, wait for its response to start, and then send the rest (Lesson 130).

Asking Once and Expecting Savings

What happens: a single question pays the write premium and never reads, so it costs more than without caching.

Fix: cache documents that will be asked about several times.


Best Practices

  • Cache documents that are large and asked about repeatedly.
  • Mark the document block, and keep questions after it.
  • Load the document once, and reuse the exact same text.
  • Ask related questions in sequence so later ones can read the entry.
  • Check the usage fields to confirm reads happen.
  • Keep the cache lifetime in mind: a long pause between questions can expire the entry (Lesson 130).

Exercise

  1. Change the order of the blocks so the question comes first, and run the example. What do the usage fields report for each question?
  2. Add an instruction at the end of HANDBOOK_TEXT that states today's date, and run the example. Does the cache still hit?
  3. Add a second document, and mark it as well. How many cache markers does the request now use?
  4. Calculate how many questions are needed before caching saves money, if the write costs 1.25 times the base price and each read costs 0.1 times the base price. Compare your answer with Lesson 126.
Show answers for steps 3 and 4

Step 3: two. One marker on each document block caches both documents as the prefix, in order, and the question after them is not cached. A second marker could also be placed to split the cache into two sections, which Lesson 129 covers. Note that the total must stay within the four-breakpoint limit, and that automatic caching uses one of those slots if you enable it.

Step 4: with one document written at 1.25 times and each later question reading it at 0.1 times, the cost for the first question is 1.25. Without caching, each question costs 1. Caching becomes cheaper after the first reuse: with one extra question, the cached total is 1.25 + 0.1 = 1.35, against 2.0 without caching. The break-even point is therefore after just one reuse, which Lesson 126 derives in more detail.

0 Comments

Reviewed before they appear

No comments yet.

Anthropic SDK Using Python
Anthropic SDK Intro Claude API Intro SDK Requirements Install Anthropic SDK Upgrade the SDK Create an API Key Set API Keys Use Environment Variables Import Anthropic Create a Client Send Your First Message Choose a Claude Model Set Max Tokens Read a Response Print Response Text Understand Message Blocks Use System Prompts Send User Messages Set Temperature Handle Stop Reasons Messages API Intro Create Messages Use Message Roles Send Conversation History Continue a Conversation Build a Chat Loop Reset Chat History Use Multiple Turns Inspect Message IDs Read Usage Data Write Clear Prompts Set a System Prompt Add Context to Prompts Use Prompt Templates Add Examples to Prompts Request JSON Output Use XML Tags Control Response Length Improve Prompt Quality Avoid Prompt Injection Read Text Blocks Read Content Blocks Check Stop Reasons Count Input Tokens Count Output Tokens Count Tokens Before Sending Limit Output Tokens Use Stop Sequences Read Request IDs Parse API Responses Streaming Intro Stream Text Output Use Stream Events Use Stream Helpers Get Final Messages Stream Async Responses Handle Stream Errors Build a Live Chat Stream Long Responses Close Streams Safely Build a Chatbot Keep Chat History Manage Chat Sessions Add Chat Memory Build a CLI Chatbot Build a Web Chatbot Use Flask with Claude Use FastAPI with Claude Return JSON from an API Add Chat Error Messages Async SDK Intro Create an Async Client Send Async Messages Use asyncio Run Parallel Requests Stream Async Text Handle Async Errors Set Async Timeouts Close Async Clients Choose Sync or Async Tool Use Intro Define a Tool Create Tool Schemas Send Tools to Claude Read Tool Calls Run Python Tools Return Tool Results Continue After Tool Use Control Tool Choice Handle Tool Errors Use the beta_tool Decorator Create a Tool Runner Add Tool Docstrings Validate Tool Inputs Use Multiple Tools Limit Tool Calls Log Tool Activity Build a Weather Tool Build a Search Tool Build a Calculator Tool Structured Output Intro Request JSON Data Validate JSON Output Use Pydantic Models Handle Invalid JSON Extract Fields from Text Generate Typed Data Use Image URLs Send Base64 Images Read PDFs with Claude Use Output Schemas Build Data Extraction Test Structured Responses Send Image Inputs Upload Files Use File IDs Process Text Files Summarize Documents Extract Table Data Handle File Errors Read Cache Usage Reduce Repeated Input Costs Debug Cache Misses Prompt Caching Intro Enable Prompt Caching Cache System Prompts Cache Long Context Test Cache Performance Use Cache Breakpoints Cache Best Practices Message Batches Intro Create a Message Batch Set Batch IDs Check Batch Status List Message Batches Get Batch Results Process Batch Outputs Handle Failed Batch Items Use Batches for Bulk Tasks Compare Batches and Requests Handle API Errors Handle Rate Limits Retry Failed Requests Set Request Timeouts Handle Network Errors Use Exponential Backoff Build Reliable API Calls Use Extended Thinking Log API Errors Track Request IDs Paginate API Results Set Thinking Budgets Read Thinking Blocks Use Tool Search Use Web Search Tools Use Computer Tools Use Citations Use Token Counting Read Raw Responses Set Custom Headers Use Claude on AWS Bedrock Use Claude on Vertex AI Use Claude on Microsoft Foundry Configure Cloud Credentials Choose a Cloud Provider Compare API Integrations Configure Provider Clients Handle Cloud Errors Use Cloud SDK Extras Deploy Cloud Apps Protect API Keys Use a .env File Ignore Secrets in Git Validate User Input Reduce Prompt Injection Limit Tool Permissions Avoid Unsafe Tool Calls Sanitize Tool Results Set Usage Limits Review Security Logs Test SDK Functions Mock API Responses Test Error Handling Test Streaming Code Measure Token Usage Track API Costs Configure Logging Deploy with Docker Deploy a FastAPI App Monitor Production Apps Build a Claude Chatbot Build a Text Summarizer Build a Code Explainer Build a JSON Extractor Build a PDF Assistant Build a Streaming Chat App Build a Tool-Calling Agent Build a Batch Processor Build a Research Assistant Build a Claude API Dashboard
Ask about this post
AI Ask about this post

Ask questions about Cache Long Context and get answers drawn from it.

Signed-in readers only.