Prompt Caching

Cache a large, stable prompt prefix so repeated requests are much cheaper and faster.

If many requests share a large, unchanging chunk of text — a big system prompt, a long document, few-shot examples — prompt caching lets Claude reuse that work instead of reprocessing it every time.

How it helps

  • Cheaper — cached tokens cost a fraction of full price.
  • Faster — the model skips re-reading the cached prefix.

The one rule to remember

Caching is a prefix match: it works on the stable part at the start of your prompt. Keep the unchanging content first and put the varying part (the user's question) last. Any change to the prefix invalidates the cache.

Example

Example · javascript
// Mark the large, stable system prompt as cacheable
const res = await client.messages.create({
  model: "claude-opus-4-8", max_tokens: 512,
  system: [{
    type: "text",
    text: LARGE_STABLE_INSTRUCTIONS, // same every request
    cache_control: { type: "ephemeral" },
  }],
  messages: [{ role: "user", content: userQuestion }], // varies per call
});

console.log("served from cache:", res.usage.cache_read_input_tokens);

When to use it

  • Cache a 10,000-token system prompt containing your product catalogue so repeat searches cost 90% less.
  • Pin a large few-shot example block with cache_control so each new user request only pays for its small user turn.
  • Cache a legal document that Claude must reference in every request, sharing the cache hit across all users.

More examples

Mark a system prompt for caching

Wraps the large stable prefix with cache_control so Anthropic caches it and bills subsequent hits at ~10% of normal.

Example · javascript
const msg = await client.messages.create({
  model: "claude-haiku-4-5",
  max_tokens: 256,
  system: [
    {
      type: "text",
      text: LARGE_KNOWLEDGE_BASE, // e.g. 5,000+ tokens
      cache_control: { type: "ephemeral" },
    }
  ],
  messages: [{ role: "user", content: userQuestion }],
});

Check cache usage in the response

Reads the cache-specific usage fields to confirm the cache was hit and measure the savings.

Example · javascript
const msg = await client.messages.create({ /* request with cache_control */ });

const { input_tokens, cache_creation_input_tokens, cache_read_input_tokens } = msg.usage;
console.log("Fresh tokens:",    input_tokens);
console.log("Cache creation:",  cache_creation_input_tokens);
console.log("Cache read (cheap):", cache_read_input_tokens);

Cache a long document for analysis

Shows two consecutive requests with the same cached document — the second is significantly cheaper.

Example · javascript
const doc = await fs.readFile("./legal-terms.txt", "utf8");

// First request: creates the cache (slightly more expensive)
const msg1 = await client.messages.create({
  model: "claude-sonnet-4-5",
  max_tokens: 128,
  system: [{ type: "text", text: doc, cache_control: { type: "ephemeral" } }],
  messages: [{ role: "user", content: "What is the cancellation policy?" }],
});

// Second request: hits the cache (much cheaper)
const msg2 = await client.messages.create({
  model: "claude-sonnet-4-5",
  max_tokens: 128,
  system: [{ type: "text", text: doc, cache_control: { type: "ephemeral" } }],
  messages: [{ role: "user", content: "What is the refund window?" }],
});

Discussion

  • Be the first to comment on this lesson.