Overview
Most production prompts repeat themselves. A support assistant sends the same instructions and the same handbook on every request, and only the user’s question changes at the end. Prompt caching lets the model provider reuse the tokens it has already processed for that repeated opening text, the prompt prefix. Cached tokens are billed at a reduced rate and the response starts sooner. In this tutorial you’ll take a prompt that never hits the cache, restructure it so it does, turn on caching for Claude and OpenAI models, and prove it works by reading the cache fields inusage.
What You’ll Build
You’ll build:- A cache-friendly prompt layout with a stable prefix and a changing suffix
- A usage reader that pulls cache reads and writes out of any Gloo AI response shape
- Explicit caching for Claude, with the
X-Cache-TTLheader on Completions andcache_controlon the Anthropic Messages endpoint - Cache-aware routing for OpenAI models, with
prompt_cache_key - A before/after comparison that reports cache hits, latency and input-token savings for your own prompt
Prerequisites
You need:- A Gloo AI Studio account
- Your API key from the API Keys page, exported as
GLOO_API_KEY - Authentication setup: complete the Authentication Tutorial first
- Python 3.10+ with
requests, or Node.js 18+ (the TypeScript examples use the built-infetch)
handbook.md next to your script. Caching only starts above a minimum prompt length (see Step 1), so aim for a few thousand words.
How Caching Works Through Gloo AI
Each provider caches in its own way. Through Gloo AI you either do nothing, or set one header or field:
Whatever the provider, a cache hit needs the same thing: the beginning of the prompt must be identical, token for token, to a recent request. Most of this tutorial is about getting that right.
The Supported Models catalog shows which models cache and how. For every provider’s rates and rules, see the Prompt Caching guide.
Step 1: Put the Stable Content First
A cache matches from the first token forward and stops at the first difference. Anything that changes per request, placed early, breaks the match for everything after it.A prompt that never caches
The same prompt, cache-friendly
Rules for a stable prefix
- Order content from most stable to least stable: instructions, then reference documents, then conversation history, then the new question.
- Move per-request values to the end: timestamps, user names, request IDs, retrieved snippets that differ per question.
- Keep the prefix deterministic: build it from the same template every time. Don’t shuffle examples, re-serialize JSON with a different key order, or reorder tool definitions between requests.
-
Make the prefix long enough to cache. Providers only cache above a minimum length:
- Version the prefix. When you change the instructions or the handbook, treat it as a new prefix. The first request after a change writes a new cache entry.
Step 2: Read the Cache Fields in usage
Every response reports its token counts in usage. Cache activity appears there too, but the field names depend on the endpoint’s response shape:
For example, a Direct Completions response reports:
- First request with a new prefix:
cache_readis0. On Claude,cache_writeis above0: the prefix was just stored. - The same prefix again, soon after:
cache_readis above0. That’s a cache hit. - OpenAI, Gemini and other implicit providers: watch
cache_read. Many of these models charge nothing to write the cache, but some do, including the Gemini models and some newer OpenAI models; the models endpoint shows which.
Step 3: Turn On Caching for Claude with X-Cache-TTL
Claude models cache only when you ask. On the guarded Completions V2 endpoint, add the X-Cache-TTL header to opt in; you don’t change your message content.
Some newer Claude models read from the cache for less: 5% of the input rate on Claude Opus 5.5 and Sonnet 5.5, and 2.5% on Claude Fable 5.1.
GET /platform/v2/models lists the exact cache_read and cache_write rates for each model.
Send the same question twice and compare usage:
What You’ll See
The two questions differ, but the system message is the same, so the second request reads the prefix from cache. Your counts depend on your handbook and the model; the pattern looks like this:cache_read stays at 0, jump to Troubleshooting.
Choosing 5m or 1h
The write premium is paid once per cache entry; the read discount is earned on every hit. Measured in input-token equivalents for each cached prefix token:
5m: a write costs an extra 0.25, each hit saves 0.9 at a 10% read rate (0.95 on Claude Opus 5.5, the model in this tutorial). One hit within five minutes already pays for the write.1h: a write costs an extra 1.0, each hit saves 0.9 or more. It pays for itself from the second hit, and keeps the cache warm through quieter periods.
5m for steady traffic, where the same prefix is requested every few minutes. Consider 1h when requests for a prefix are spread out, for example a document a team asks about a few times an hour.
Your own cache breakpoints
WithX-Cache-TTL on Completions V2, add at most three cache_control markers of your own on your message content. If your request already has four of its own, the request still succeeds, but your system messages aren’t cached on that call.
Step 4: Use cache_control on Anthropic Messages
If your code uses the Anthropic SDK, point it at the Anthropic Messages endpoint. There, cache_control works as it does on Anthropic’s own API: set it at the top level to cache automatically, or on individual content blocks for fine-grained control.
Marking the system block caches everything up to and including it:
usage.cache_creation_input_tokens (first call) and usage.cache_read_input_tokens (second call). Pass your Gloo API key as the SDK’s auth token (auth_token in Python, authToken in TypeScript); see Set up the SDK.
Anthropic Messages is a direct endpoint: it bills the model’s published rate, and no guardrails or values alignment run. Pick the endpoint for what your application needs; caching works on both.
Step 5: Improve OpenAI Hit Rates with prompt_cache_key
OpenAI caches automatically once a prompt reaches 1,024 tokens, with no write fee on most models. Requests are routed to servers that recently processed the same prefix. Add prompt_cache_key to the request body to make requests that share a prefix more likely to land on the same server:
prompt_cache_key is also accepted on Responses and Direct Responses, and is silently ignored for models from other providers, so it’s safe to send on every request.
The cache read rate depends on the model: usually 10% of the input rate on GPT-5 and later models, and 25% on GPT-4.1. Some newer models, such as GPT-5.6 and GPT-6, also charge a cache write. Check each model’s exact rates with GET /platform/v2/models.
Step 6: Gemini, DeepSeek and Other Implicit Providers
Nothing to switch on: noX-Cache-TTL, cache_control or prompt_cache_key. Repeated prefixes are cached by the provider, and hits are billed as a separate cache_read segment at the model’s reduced rate.
The work is all in Step 1: a stable prefix above the model’s minimum length. Run the same two-question test from Step 3 without the header, and check cache_read.
Cache read rates vary by model. Gemini cache reads are usually 10% of the input rate, and Gemini models also charge a cache write. Open-weight models such as DeepSeek, Qwen and MiniMax range from under 1% to more than half of the input rate, and some Qwen models charge a cache write too. Not every model in this group caches. The models endpoint is the source of truth for each model’s cache pricing.
Step 7: Compare Before and After
Measure the effect on your own traffic. This script sends the same set of questions twice: once with a prompt that changes at the start (the “before” layout from Step 1), and once with the stable prefix. It totals cache reads, cache writes and latency, then converts the cache counts into input-token equivalents saved, using the rates from the Prompt Caching guide:X-Cache-TTL: 5m, write_ratio is 1.25 and read_ratio is 0.10 on most models (0.05 on Claude Opus 5.5, the model used here). For a GPT-5 model with no write fee, such as GPT-5.5, read_ratio is 0.10 and write_ratio is 1.0. For any other model, take both ratios from the models endpoint: divide cache_read and cache_write by input.
What You’ll See
With the “before” layout, every request starts with a different timestamp, so every request writes a new cache entry and none reads one. With the stable prefix, the first request writes the cache and the next three read it. Illustrative output for a 6,000-token handbook:readis the number of prompt tokens billed at the cache read rate instead of the full input rate.savedis how many full-price input tokens those reads were worth, after paying for the write. Multiply by the model’s input rate fromGET /platform/v2/modelsto turn it into money for your own volume.- Latency typically drops on cache hits; how much depends on the model and prompt length, so measure it for your workload.
Step 8: Keep the Cache Warm in Production
These habits keep the hit rate high in production, expanding on the caching best practices in the guide:- Pre-warm on startup. Send one request with your standard system prompt when your service starts, so the first real user reads from cache rather than paying for the write.
- Expect a dip after failover. Caches are held by each provider. When the provider serving your model fails and Gloo AI fails over to another provider of the same model, that request doesn’t read the cache built on the first provider. Cached tokens recover as the cache warms on the new provider. Don’t alert on a single cold request; watch the hit rate over time.
- Log cache stats. Record
cache_readandcache_writewith each request, next to the model and the prefix version (orprompt_cache_key). A sudden drop to zero usually means something started changing the prefix. - Keep long conversations cache-friendly. In multi-turn chat, append new turns to the end and never rewrite earlier ones, so each request extends the previous prefix.
Troubleshooting
cache_read is always 0 on Claude
: Check that the X-Cache-TTL header is sent with 5m or 1h on every request (on Anthropic Messages, check cache_control instead). Check the prefix is above the model’s minimum cacheable length. If your request already carries four cache_control markers of its own, your system messages aren’t cached; remove one.
cache_read is 0 on the second request, but cache_write is above 0 both times
: Something in the prefix changes between requests. Diff the two system messages byte for byte: look for timestamps, IDs, user names, randomized examples, or JSON serialized with a different key order.
Hits stop after a few minutes
: X-Cache-TTL: 5m sets a five-minute cache lifetime. If your traffic is sparse, try 1h and compare the totals with Step 7.
OpenAI requests rarely hit
: Make sure the prompt is at least 1,024 tokens, and add a stable prompt_cache_key. A key that changes per request or per user spreads requests across servers and lowers the hit rate.
prompt_cache_key has no effect
: It only applies to OpenAI models and is ignored for other providers. For Claude, use X-Cache-TTL or cache_control.
Cached tokens drop for a while, then recover
: The request was most likely served by a different provider of the same model after a failover, which starts with a cold cache. See Provider Failover.
The detail objects are missing from usage
: They’re present when the provider reports them. The cache_stats helper treats a missing field as 0; if a model never reports cache counts, check its caching support in Supported Models.
Next Steps
Prompt Caching Guide
Every provider’s caching type, billing rates and minimum lengths.
Build a Resilient Client
Retries, backoff and stream recovery around your cached requests.
Provider Failover
What happens to your request, and your cache, when a provider fails.
Get Models API
Current per-model rates and capabilities.
Cost and Speed
How caching fits with model choice and reasoning effort to lower cost.
Context Is King
How to structure the context you put in a prompt.
Best Practices
Production patterns for reliable, trustworthy applications.

