Blank white background with no objects or features visible.

TrueForgeのご紹介:オープンソースでベンダーフリーなエージェントハーネス。コストを50%削減します。今すぐ試す→

プロバイダーに依存しないプロンプトキャッシュ:LLMゲートウェイがAnthropic、OpenAI、Bedrockをどのように正規化するか

By Boyu Wang

Published: September 11, 2026

Every major LLM provider implements prompt caching differently. Here's how the TrueFoundry AI Gateway translates cache directives across providers, handles fallback when a target doesn't support caching, and exposes unified hit metrics — with token savings benchmarks.

The first time we saw a 10,000-token system prompt billed at full price 950 times in a single hour — on a deployment that was supposed to have caching turned on — the on-call engineer's Slack message was four words: "where did it go?" The cache_control directive was set. The prefix was identical byte-for-byte across every request. Anthropic's API was happily caching the traffic that reached it. The catch was that half the requests had been routed to a different provider during a brief failover, and the gateway translating between them had quietly dropped the cache directive on the floor — no error, no warning, just a $30 line item where there should have been a $3 one. The bill recovered. The trust took longer. This post is about everything that has to go right for that not to happen to you.

Prompt caching is the single highest-leverage cost optimization for any LLM workload built on a long, stable prefix — a 10K-token system prompt, a tool registry, a retrieval bundle. The discount is roughly 90% off cached input tokens, large enough to change the unit economics of an agent product.

Figure 1 — A canonical request enters the TrueFoundry AI Gateway, which translates it into three native dialects on the way out. Each provider returns a different usage shape; the gateway normalizes back to a single object downstream consumers can rely on.

The catch is that the three major LLM provider APIs — Anthropic native, OpenAI, AWS Bedrock Converse — each model caching differently in ways that aren't cosmetic: directive shape, response shape, TTL options, and even when caching is invoked at all.

The Core Idea
Three native cache APIs, one unified directive at the gateway
Anthropic uses explicit cache_control breakpoints. OpenAI caches automatically on long prefixes. Bedrock Converse uses cachePoint markers. A gateway that doesn't normalize all three forces provider-specific branches into routing, cost attribution, and observability — and silently misprices every request that takes a path the code didn't test.

1 Anthropic Prompt Caching: Explicit Breakpoints and the 5-Minute TTL

Anthropic's prompt caching is the most expressive of the three. You explicitly mark which portion of the request should be cached using the cache_control attribute on a system or message block:

anthropic request · json

{
  "model": "claude-sonnet-4-6",
  "system": [{
    "type": "text",
    "text": "<10,000 token system prompt>",
    "cache_control": {"type": "ephemeral"}
  }],
  "messages": [{"role": "user", "content": "<query>"}]
}

Three rules govern when this actually caches. The prefix must clear a model-specific minimum: 1,024 tokens for Sonnet-class and 2,048 tokens for Opus-class. Below the threshold the directive is silently dropped. The default TTL is 5 minutes, refreshed on each hit. And the prefix must be byte-identical — a stray timestamp before the cached block kills the hit (we return to this in §08).

Pricing has two non-obvious components. Cache reads are billed at 10% of the base input rate — the 90% discount you came for. Cache writes carry a 25% premium over base input pricing. The cache must pay for itself across enough subsequent hits to recover the write surcharge; for a 10K-token prefix on Sonnet 4.6, breakeven is two follow-up hits.

The response surfaces caching in three usage fields: cache_read_input_tokens (served from cache), cache_creation_input_tokens (written this turn), and input_tokens (everything else). Since extended-TTL caching now lets you opt into a 1-hour retention at a 2× write premium, Anthropic also surfaces a per-TTL breakdown under cache_creation.ephemeral_5m_input_tokens and cache_creation.ephemeral_1h_input_tokens. That breakdown matters more than it looks — we'll come back to it in §04.

2 OpenAI Automatic Caching: Implicit Prefixes and the 1-Hour Window

OpenAI's prompt caching takes the opposite philosophy. There is no directive. The cache turns on automatically once the prompt prefix exceeds 1,024 tokens, and OpenAI's infrastructure caches the KV activations server-side. Subsequent requests with the same prefix get the cached state automatically.

The developer-facing surface is two optional parameters that influence — but don't trigger — caching. prompt_cache_key is a string combined with the prefix hash to influence backend routing: same key, same backend, higher hit rate. prompt_cache_retention accepts "in_memory" (default, 5–10 minutes) or "24h" for extended retention. Both are documented in OpenAI's prompt caching guide.

The asymmetry with Anthropic is sharp: you cannot choose which prefix is cached. OpenAI's caching layer picks the longest repeated prefix it observes on a given backend. If your system prompt is followed by a frequently-changing tool registry, the cache may land on the system prompt alone or on a different boundary, with no visibility into which. The response surfaces only one cache field — cached_tokens nested under usage.prompt_tokens_details — and no write-side counter, because OpenAI doesn't bill for cache writes.

The practical implication: OpenAI caching is well-suited to workloads where the stable prefix is one block. Anthropic's explicit breakpoints give you fine-grained control over multi-region prefixes; OpenAI doesn't.

3 AWS Bedrock Prompt Caching: The Converse API Approach

Bedrock's prompt caching sits in the Converse API and uses a cachePoint marker block placed after the content it caches:

bedrock converse · json

{
  "modelId": "anthropic.claude-sonnet-4-6-v1:0",
  "system": [
    {"text": "<long system prompt>"},
    {"cachePoint": {"type": "default", "ttl": "1h"}}
  ],
  "messages": [/* ... */]
}

Three things make this trickier than it looks. First, the marker placement is the opposite of Anthropic's — the directive comes after the content it caches, not on it. Implementations that lift Anthropic's pattern directly silently disable caching. Second, this is the Converse API specifically; Bedrock's native InvokeModel endpoint accepts the Anthropic-style format verbatim for Claude models, but Converse is the path most newer integrations use.

Third, TTL support shifted recently. Before January 26, 2026, Bedrock Converse only supported a 5-minute TTL. On that date AWS shipped 1-hour TTL support for the Claude 4.5+ family and Amazon Nova; the new ttl: "1h" field on the cachePoint opts in. Older models reject the field — no graceful downgrade.

The response uses camelCase: cacheReadInputTokens, cacheWriteInputTokens, and inputTokens. Unlike Anthropic, Bedrock Converse does not expose a per-TTL breakdown on writes. The gateway that translated the request knows which TTL was requested; the response alone doesn't tell you.

Sharp Edge
Bedrock's 1-hour TTL is Claude 4.5+ only. Sending ttl: "1h" to an older model returns an API error, not a downgrade. TrueFoundry's router resolves model fallbacks before the cache translation step, not after, so the TTL it commits to always matches a model that can honor it.

4 Gateway Normalization: What Happens When the Target Doesn't Support Caching

The translation problem the gateway has to solve is: a client sends a single canonical request with Anthropic-style cache_control, and the gateway routes to whichever provider the policy selects. Three strategies are possible — strip the directive when the target doesn't understand it, translate to the target's native cache primitive, or error and refuse to route.

TrueFoundryのゲートウェイは、 可能な場合は翻訳し、そうでない場合は削除してログに記録します。AnthropicとBedrock Converseには完全な翻訳が適用されます — cache_control というTTLを持つものは cachePoint と、それと同等の ttl フィールドになります。OpenAIでは意図が翻訳されます。ディレクティブ自体は破棄されますが、 prompt_cache_retention"24h" に設定され、1時間の正規TTLの場合、 prompt_cache_key は正規の cache_keyから転送されます。ダウングレードが強制された場合 — 拡張TTLをサポートしないモデルに1時間のTTLがルーティングされる場合 — ゲートウェイは警告スパン属性 (gen_ai.tfy.cache_ttl_downgrade=5m) を出力し、回帰が観測可能になります。

レスポンス側でのより巧妙な落とし穴の1つは、混合TTLコスト計算バグです。

図2 — Anthropicからの応答には、同じ呼び出し内で5分と1時間の両方の書き込みトークンが含まれることがあります。これらをコスト計算のために単一のTTLラベルにまとめることは、キャッシュ書き込みのたびに19〜29%の誤差を生じさせます。統合された使用状況の形式は、この内訳を保持する必要があります。

したがって、ゲートウェイがダウンストリームに公開する統合使用量オブジェクトには、4つではなく5つのトークンフィールドがあります。 cache_hit_tokenscache_miss_tokenscache_write_5m_tokenscache_write_1h_tokens、および。

5 フォールバック時のキャッシュの動作:コールドスタートとコストへの影響

複数のプロバイダーに対応するゲートウェイにとって興味深い障害モードは、プライマリターゲットがレート制限されたりダウンしたりして、リクエストがセカンダリにフォールバックする場合に何が起こるかです。キャッシングに関しては、 キャッシュはプロバイダー間でトラフィックを追跡しません。 過去15分間Anthropicのキャッシュでホットだった1万トークンのシステムプロンプトを持つリクエストは、Azure OpenAIへのフォールバック時に、完全にコールドなプレフィックスキャッシュにヒットします。フォールバックは成功しますが、プレフィックスに対しては入力トークンの全コストを支払い、トレースは正しくキャッシュミスを報告します。

Sonnet 4.6で1万トークンのプレフィックスの場合、これはリクエストあたり0.003ドル(キャッシュ読み取り)と0.030ドル(フル入力)の差となり、フェイルオーバー期間中にコストが10倍に跳ね上がります。セカンダリがウォームアップした後でも、ウォームアップは無料ではありません。コールドターゲットへの新しいリクエストごとに、書き込みプレミアムが発生します。

この緩和策には2つの部分があります。 セカンダリをウォームアップ状態に保つ — インシデント時だけでなく、継続的にトラフィックの1%をフォールバックプロバイダーに送信します。 フォールバックキャッシュヒット率を別途監視する役立つアラートは「フォールバック率が5%を超過しました」ではなく、「フォールバック率が5%を超過し、かつフォールバックキャッシュヒット率が50%未満です」というものです。前者はルーティングイベントであり、後者は測定可能なコストペナルティを伴うルーティングイベントです。

6 統合キャッシュメトリクス:ゲートウェイがプロバイダー全体でヒット率を可視化する方法

正規化レイヤーの利点は、どのプロバイダーがリクエストを処理したかに関わらず、すべてのトレーススパンが同じキャッシュ属性を持つことです。

otel span attributes · gateway-emitted

gen_ai.provider.name              = anthropic
gen_ai.request.model              = claude-sonnet-4-6
gen_ai.usage.cache_hit_tokens     = 9800
gen_ai.usage.cache_miss_tokens    = 248
gen_ai.usage.cache_write_tokens   = 0
gen_ai.usage.output_tokens        = 503
gen_ai.cache.hit_rate             = 0.975
gen_ai.cache.ttl_tier             = 1h
gen_ai.tfy.virtual_account        = tenant-123

どのダッシュボードクエリ、コストアトリビューションジョブ、ルーティング調整分析も、プロバイダーごとに分岐することなくこれらのフィールドを読み取ることができます。それらから計算されたキャッシュヒット率は、Anthropic、OpenAI、Bedrockのトラフィック間で比較可能であり、これにより、3つの異なるSQLテンプレートを使用することなく、1つのダッシュボードパネルで「このワークロードでどのプロバイダーが最高のキャッシュ経済性を提供しているか」という問いに答えることができます。

2つの注意点があります。キャッシュ固有の属性はOTelの gen_ai.* 名前空間パターンに従いますが、公式のセマンティック規約仕様の一部ではありません(現時点では)。そして hit_rate は運用上役立つ要約であり、正確な効率性指標ではありません。フォレンジックなコスト照合のためには、基となるトークンフィールドを直接読み取ってください。

7 トークン節約ベンチマーク:1万トークンのシステムプロンプト、1,000リクエスト

ほとんどのエージェントアプリケーションが実際に実行するワークロードは、安定した1万トークンのシステムプロンプト、リクエストごとに変化する200トークンのユーザークエリ、500トークンのモデル応答、そしてセッションウィンドウ全体で1,000リクエストです。現実的な95%のキャッシュヒット率(アイドル期間中のTTL期限切れによる950ヒット、50ミス)を仮定します。すべての数値は、2026年5月の定価に対する米ドル建てです。

図3 — 1,000リクエスト、同一ワークロード、3つの料金パス。Anthropicのキャッシュは総コストを66%削減し、OpenAIの自動キャッシュは69%削減します。残りのコストの大部分は出力トークンであり、これはどちらのプロバイダーのプレフィックスキャッシュも影響しません。

2つの点が際立っています。両プロバイダーは大きく、ほぼ同等の節約を提供しており、キャッシュなしの場合との差に比べて、両者間の差は小さいです。そして、キャッシュが有効になると、出力トークンが主要なコスト項目になります(Anthropicの総コストの約58%、OpenAIの総コストの約65%)。これにより、次にどの最適化が重要になるかが変わります。キャッシュが有効になると、次のコスト削減は出力長の制御から得られ、より深い入力最適化からではありません。

8 ヒット率を低下させるプロンプトキャッシュのアンチパターン

キャッシュキーは、上記の工夫が適用される前はバイト単位で完全一致します。いくつかの一般的なパターンが、気づかれないうちにヒット率を低下させますが、それらはすべて同じ形をしています。 不安定なものが、安定しているはずのプレフィックスの前や内部に連結されてしまうことです。

Timestamps inside the system prompt
"Today is {{date}}." produces a new cache key every day. If the date matters, put it in the user message, not the system prompt.
Request IDs / correlation tokens in the prefix
Injecting a UUID for downstream logging defeats caching entirely. Pass these as message metadata, not prompt content.
Per-user system prompts
"You are talking to {{user_name}}." produces N caches for N users. Personalize in the first user-turn message instead.
Randomized tool order
Some agent frameworks shuffle tools to combat positional bias. The shuffle changes the byte sequence and kills the cache.
Model swaps between turns
Caches are model-scoped. Routing turn N to Sonnet and turn N+1 to Haiku means turn N+1 starts cold.
A/B-testing prompt edits
Half-and-half experiments fragment the cache. Run A/B tests at the user level so each cohort builds a coherent cache.

ゲートウェイは、仮想アカウントごとのキャッシュヒット率を監視することで、これらのほとんどを自動的に検出できます。10Kトークンのシステムプロンプトでヒット率が常に40%を下回る場合、それはほぼ間違いなくコンテンツの揮発性に関する問題であり、トレースのタイムラインは通常、どのセグメントが変化しているかを示します。TrueFoundryのダッシュボードでは、これを「低キャッシュヒット率」アラートとして、プレフィックスの差分情報とともに表示するため、修正は通常5分程度のプロンプト編集で済みます。

9 よくある質問

Do I have to use Anthropic's cache_control syntax even if I'm only calling OpenAI?
No — but it costs you nothing and gives you portability. If you write client code against cache_control and later route a subset of traffic through Anthropic or Bedrock, no client changes are needed. If you write it against OpenAI's parameters directly, every future provider addition becomes a client-side refactor.
What's the minimum prefix length that actually caches?
1,024 tokens for Anthropic Sonnet-class and OpenAI; 2,048 for Anthropic Opus-class; 1,024 for Bedrock Converse. Below the threshold the directive is accepted and silently dropped. If you're not seeing hits on what you thought was a long prefix, count the tokens before assuming the cache is broken.
How does the gateway handle a 1-hour TTL request when the routed model doesn't support it?
Model resolution happens before cache translation. If the router lands on a model that doesn't support extended TTL, the translator emits the 5-minute default and tags the span with gen_ai.tfy.cache_ttl_downgrade=5m — the downgrade is visible in the trace.
Can I share a cache across providers — Anthropic and Bedrock both serve Claude?
No. Caches are infrastructure-scoped — even though Anthropic's API and Bedrock's Claude routes use the same model weights, the KV cache lives in different machines on different accounts. Sending the same request to both targets builds two independent caches and pays the write surcharge twice.
How does this compose with semantic caching at the gateway?
The two layers are complementary. Provider prompt caching reduces input-token cost but still generates a fresh output; semantic caching at the gateway eliminates the model call entirely on a hit. Use semantic cache as the first lookup, provider cache as the fallback. We cover the gateway layer in Semantic Caching: When Text Stops Being the Right Cache Key.
Is there a way to verify cache-attribution math against the actual bill?
Yes — pull each provider's billing export for a fixed window, sum the gateway's computed costs over the same window grouped by provider and TTL tier, and reconcile. If the gateway's number is more than ~2% off the bill, something in the normalization path is wrong; under 2% is usually rounding.

Try now.

One gateway for all your models, MCP servers, and agents.
No credit card needed.

Start free
Table of Contents

One Gateway for Every LLM, Agent and MCP Server

Book a 30-min with our AI expert

Book a Demo

The fastest way to build, govern and scale your AI

Book Demo
Summarize with
ChatGPT logo by OpenAI
Perplexity AI logo
Blurry red snowflake on white background, symmetrical frosty design with soft edges and abstract shape.

Discover More

No items found.
September 11, 2026
|
5 min read

セキュリティログにAIを導入する前に、EUのSOCチームが問うべきこと

LLM・生成AI
September 11, 2026
|
5 min read

AIの混沌を制御へ変える:Tesseract TalksとのエージェンティックAIに関する対談

No items found.
September 11, 2026
|
5 min read

TrueFoundry vs Portkey vs Helicone: 2026年版エンタープライズAIゲートウェイ比較

No items found.
September 11, 2026
|
5 min read

TrueFoundry MCP Gateway:2026年の生産的で安全なエンタープライズAIのための重要インフラストラクチャ

No items found.
No items found.

Recent Blogs

Black left pointing arrow symbol on white background, directional indicator.
Black left pointing arrow symbol on white background, directional indicator.
Take a quick product tour
Start Product Tour
Product Tour