Your agent sends the same system prompt, tool definitions, schemas, and policy instructions on every turn. In a 6-turn session, you can get billed for that same opening block 6 times, even though the only thing that changed is the user’s latest message or the agent’s latest tool result.

The Cheapest Token Is a Cached One: Prompt Caching + Sticky Routing

Prompt caching fixes that. The provider reads the repeated part of your prompt from cache instead of charging you full price for it every time. Sticky routing keeps that working across turns by sending a session back to the same provider that holds the warm cache.

This post covers the money side: what cached tokens cost, why cache reads and writes are priced differently, how session_id keeps an agent’s session warm from turn one, and how to check that caching is actually working.

A cache read costs 0.1x to 0.5x of normal input pricing, depending on the provider. That range is why caching can make agent loops much cheaper.

The repeated part is usually the expensive part: a long system prompt, tool definitions, JSON schemas, guardrails, retrieved documents, or examples that keep the model consistent. Without caching, each turn pays full price for all of it again. With caching, the first request writes it to the cache, and later requests read it back at the cheaper rate.

The prompt caching docs:https://openrouter.ai/docs/guides/best-practices/prompt-caching have the full breakdown. The exact dollar amount still depends on the model and provider route; the multiplier tells you how cached input compares with normal input for that provider.

For agent builders, the pattern is simple: the first turn may pay to set up the cache, but every turn after that gets much cheaper as long as the same opening block is reused.

Prompt caching has two costs: the write and the read.

The write happens when the provider stores the reusable part of the prompt. The read happens when a later request reuses that stored content. You come out ahead once the same content gets read enough times to cover the write.

On some providers, the write costs more than normal input. Anthropic cache writes cost 1.25x input for the default 5-minute TTL and 2.0x input for the 1-hour TTL. A single Anthropic cache write that’s never reused costs more than sending the same prompt without caching.

For a one-off request, caching may not help. For a multi-turn agent, repetition is the default: the agent carries the same instructions, tools, schemas, and policy context across the whole session. So the write pays for itself over a few turns.

Use the 5-minute cache lifetime (TTL) for short bursts where the next turn arrives quickly. Use the 1-hour one when a session may pause long enough for the default cache to expire, but the content is still worth keeping around.

A warm cache only helps if the next request lands on the provider endpoint that holds it.

When requests can route to many providers, turn one can write a cache on one provider while turn two lands somewhere else. The second provider has no warm cache to read from. The request still works, but you pay full price and cached_tokens stays low or zero.

That’s why we pair sticky routing with prompt caching. After a cached request, we route follow-up requests for the same model back to the same provider endpoint when that provider’s cache-read pricing is cheaper than normal input. If that sticky provider becomes unavailable, OpenRouter falls back to the next available provider instead of failing the request.

By default, OpenRouter recognizes a conversation by hashing its first system or developer message and its first non-system message. That works when those opening messages stay the same.

Agents often break that. Some rewrite their first messages as they summarize state, reorder tool context, or add new run metadata. When the opening messages change, the hash changes, and the conversation can land on a different provider. The fix is an explicit session_id .

Diagram of an agent session where session_id keeps turns 1 through N on the same provider for cache writes and cheap cache reads, with automatic failover to a new provider if the sticky one fails

For agent loops, set session_id . When you pass it, OpenRouter uses it directly as the sticky routing key instead of deriving a key from the opening messages.

With session_id , sticky routing kicks in after the first successful request, before any cache hit has happened. Without it, stickiness only starts after a cache hit is detected. For multi-turn agents, that’s the difference between a cache that’s reliable from turn one and one that’s only sometimes warm.

You can send session_id as a top-level request body field or through the x-session-id header. Keep it stable for the conversation or agent run, and keep it under 256 characters.

Use a value that matches the unit of work: a chat thread, ticket, workflow run, or agent task. Don’t create a new session_id for every turn, or requests stop landing on the provider that holds the cache.

If you use router models such as Auto Router:https://openrouter.ai/docs/guides/routing/routers/auto-router#session-stickiness or Pareto Router:https://openrouter.ai/docs/guides/routing/routers/pareto-router#session-stickiness, session stickiness also pins the model the router picked, not just the provider. That keeps the conversation from switching models mid-session, so behavior stays consistent and the cache stays warm.

The fastest way to check is to inspect usage:https://openrouter.ai/docs/cookbook/administration/usage-accounting.

In the response, usage.prompt_tokens_details.cached_tokens shows how many tokens were read from cache. If it’s greater than zero, the request hit the cache. cache_write_tokens shows how many tokens were written during a cache-write request.

In this example, most of the prompt tokens came from cache, and this turn didn’t write a new cache entry.

You can inspect cache behavior in three places: the detail view on the Activity page:https://openrouter.ai/activity, the /api/v1/generation API, and the usage.prompt_tokens_details object returned with API responses.

Use cache_discount to see what a generation saved. On providers with paid writes, you may see a negative discount on the write turn because the cache write costs more than normal input. On later cache-read turns, the discount should turn positive.

When caching looks broken, it usually comes down to one of 4 things: the prompt is too short, the cache expired, the opening content changed, or the request moved to a different provider.

Every provider has a minimum prompt size, and below it nothing gets cached. On Anthropic, Claude Opus 4.5 through 4.8 and Claude Haiku 4.5 need 4,096 tokens; Claude Haiku 3.5 needs 2,048; Claude Sonnet 4, 4.5, and 4.6 (and Opus 4 / 4.1) need 1,024. OpenAI needs 1,024. Gemini 2.5 Pro needs 4,096; Gemini 2.5 Flash needs 1,024.

If your reusable content sits below that minimum, caching won’t start. Don’t pad the request with filler text just to force it. Use caching where you already have a lot of reusable content: tools, schemas, retrieved documents, examples, or policy text.

Caches don’t live long. Anthropic’s default is 5 minutes, with a 1-hour option for longer sessions. Gemini’s implicit cache lasts about 3-5 minutes and doesn’t reset when you read from it. Once a cache expires, the next request has to write a new one.

If your users often pause between turns, use a longer TTL where supported, or build the agent to accept a new write after idle periods.

Automatic and implicit caching work best when the start of the prompt stays the same. Put the stable stuff first: system instructions, tools, schemas, and fixed reference material. Put the changing stuff later: user questions, timestamps, temporary state, tool outputs, and short-lived metadata.

Small details count here. A timestamp in the first system message makes the prompt look new on every turn. Move it into a later user or tool message if it doesn’t need to be part of the cached content.

A cache lives where it was written. If a later request routes to a different provider endpoint, that endpoint can’t read the earlier cache.

For agent workflows, set session_id and let sticky routing keep the session on the warm provider. One catch: if you set provider.order yourself, your order wins over sticky routing. Use provider routing controls:https://openrouter.ai/docs/guides/routing/provider-selection if you need a specific provider order.

If your agent sends the same content every turn, here’s the checklist:

For a rough picture, imagine an agent that repeats the same 10,000 tokens over 6 turns.

This example covers only the repeated content. It ignores the smaller changing messages and the model’s output tokens. The savings grow with the number of turns.

When your agent sends the same expensive content again and again, cached reads and sticky routing keep it from becoming the most expensive part of the loop.

Yes. OpenRouter supports prompt caching across supported providers and models. Most providers enable it automatically, while Anthropic and Alibaba Qwen use cache_control for explicit caching. Cache reads cost 0.1x to 0.5x of normal input pricing depending on the provider, so a reused prefix gets much cheaper after the first request.

Cache reads cost 0.1x to 0.5x of normal input pricing, depending on the provider. Anthropic, DeepSeek, and Alibaba Qwen can read at 0.1x. OpenAI reads at 0.25x to 0.50x. Gemini, Grok, and Moonshot read at 0.25x. Groq reads at 0.5x.

The common causes are a prompt below the provider’s token minimum, an expired cache, an unstable prompt prefix, or provider drift between turns. For agent workflows, start by setting a stable session_id , then check cached_tokens in the usage response, where any value above zero confirms a cache hit.

Pass a stable session_id for the conversation, ticket, or workflow run. OpenRouter uses it as the sticky routing key, so follow-up requests route back to the same provider endpoint that holds the warm cache. With session_id set, stickiness activates after the first successful request, before any cache hit is observed.

Inspect usage.prompt_tokens_details.cached_tokens for cache reads and cache_write_tokens for cache writes; a cached_tokens value above zero confirms a hit. You can also read cache_discount in the response to see the per-generation cost effect, or open the detail view on the Activity page:https://openrouter.ai/activity or the /api/v1/generation API.

Yes. With a session_id set, router models such as Auto Router and Pareto Router pin both the resolved model and the provider for the conversation, so follow-up turns keep hitting the same warm cache.