Claude Media
cache_creation_5m_tokensでClaude Codeのキャッシュ書き込みを寿命別に見る

cache_creation_5m_tokensでClaude Codeのキャッシュ書き込みを寿命別に見る

Claude Code v2.1.300でapi_requestイベントに加わったcache_creation_5m_tokensとcache_creation_1h_tokensでキャッシュ書き込みを5分と1時間に分けて集計する方法です。

Claude CodeのOpenTelemetry api_request イベントには、v2.1.300から cache_creation_5m_tokens と cache_creation_1h_tokens の2属性が加わりました。キャッシュに書き込んだトークンを、5分で消える分と1時間残る分に分けて数えられます。これまでの cache_creation_tokens は両者の合計しか見えず、書き込み単価が違うのに内訳が分かりませんでした。

2つの属性で何が分かるか

changelogのv2.1.300には、api_request イベントに cache_creation_5m_tokens と cache_creation_1h_tokens を足し、キャッシュ書き込みを寿命別に分けたと書かれています。対象はメトリクスではなくイベントです。ログ側のエクスポーターを有効にしていないと届きません。

属性中身必要なバージョン
cache_creation_tokens中身キャッシュに書いたトークンの数必要なバージョン従来から
cache_creation_5m_tokens中身5分の寿命で書いた分必要なバージョンv2.1.300以降
cache_creation_1h_tokens中身1時間の寿命で書いた分必要なバージョンv2.1.300以降

寿命別の内訳は、APIのレスポンスにある usage.cache_creation の ephemeral_5m_input_tokens と ephemeral_1h_input_tokens と同じ区分です。Claude Code本体のログを解析しなくても、テレメトリー側で同じ切り分けができるようになりました。

注意点が1つあります。monitoring-usageページの api_request 属性一覧には cache_creation_tokens までしか載っておらず、新しい2属性の説明はありません。2つの合計が cache_creation_tokens と一致するかどうかも、ページには書かれていません。集計に使う前に、自分のデータで突き合わせてください。

なぜ寿命別に分けると効くのか

書き込みの単価は寿命で変わります。プロンプトキャッシュの料金表では、5分書き込みは基本入力単価の1.25倍、1時間書き込みは2倍です。読み取りは0.1倍が標準で、モデルによっては0.05倍や0.025倍になります。

基本入力単価が100万トークンあたり3ドルのモデルで、5分書き込みを20万トークン、1時間書き込みを10万トークン行ったとします。

  • 5分分: 200,000 × 3.75ドル ÷ 1,000,000 = 0.75ドル
  • 1時間分: 100,000 × 6ドル ÷ 1,000,000 = 0.60ドル

合計は1.35ドルです。同じ30万トークンでも、全部が5分書き込みなら1.125ドルで済みます。差は寿命の割合で決まるため、合計だけを見ていても、設定を変えたときの効果が追えません。

くらべる

書き込み1回あたりの単価の違い

標準

5分の寿命

基本入力単価の1.25倍です。短い間隔で会話が続くなら、読み取りに回って元が取れます。

長め

1時間の寿命

基本入力単価の2倍です。席を外す時間が長いセッションで、再書き込みを避けたいときに向きます。

どちらが得かは、次のリクエストまでの間隔で決まります。判断の枠組みはClaude Codeのキャッシュ寿命と使い分けと、API側の単価を整理したClaude APIの1時間キャッシュにあります。ここでは、その判断を数字で検証する材料に絞ります。

受け取るための設定

属性を見るには、イベントを出す設定が要ります。ログのエクスポーターを有効にします。ローカルでの確認は console が手軽です。

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_LOGS_EXPORTER=console
export OTEL_LOGS_EXPORT_INTERVAL=5000
claude --version   # 2.1.300 以上であること
claude

OTLPで送るなら OTEL_LOGS_EXPORTER=otlp に変え、エンドポイントとプロトコルを足します。受け入れ先の構成全体はClaude CodeのOpenTelemetryで利用量とコストを可視化が扱っています。

プロンプトを1つ送ったあとのログで、event.name が api_request のレコードを探します。そこに2つの属性が付いていれば、受信側まで届いています。属性が見つからない場合は、まずバージョンを確認してください。

集計の組み立て方

イベント単位の数値なので、集計はログ基盤の側で行います。バックエンドごとに構文は違うため、考え方だけ擬似コードで示します。

-- 例: セッション単位で寿命別の書き込みを足す(擬似コード)
filter event.name = "api_request"
group by session.id
sum cache_creation_5m_tokens   as write_5m
sum cache_creation_1h_tokens   as write_1h
sum cache_read_tokens          as read

ここから出せる指標は次のとおりです。

  • 1時間書き込みの比率: write_1h / (write_5m + write_1h)
  • 書き込みに対する読み取りの倍率: read / (write_5m + write_1h)
  • 概算の書き込みコスト: write_5m × 1.25 + write_1h × 2(基本入力単価に対する倍率)

倍率が低いまま1時間書き込みの比率だけ高いセッションは、長い寿命で書いたのに読まれていない状態です。逆に5分書き込みが多く、倍率も低いなら、間隔が空いて毎回書き直している可能性があります。コスト表示は近似値です。monitoring-usageのNoteにあるとおり、正式な請求は利用しているAPI提供元のデータで確認します。

同じイベントのコスト属性と突き合わせる

api_request には cost_usd と、100万分の1ドル単位の整数で出す cost_usd_micros も付きます。寿命別のトークンから前節の倍率で出した概算と、セッション単位の cost_usd の合計を並べると、集計式の誤りに気づけます。ずれが大きいときは、model ごとに基本入力単価が違う点と、読み取りの倍率がモデルで違う点を先に疑います。

設定を変えたあとの効果を測る

寿命の切り替えは、設定と環境変数で行います。promptCacheTtl はメインの会話、subagentPromptCacheTtl はそれ以外のリクエストに効き、値は 5m か 1h だけです。環境変数の CLAUDE_CODE_PROMPT_CACHE_TTL と CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL も同じ値を取ります。優先順位は FORCE_PROMPT_CACHING_5M が最上位で、次に環境変数、設定ファイルのキー、ENABLE_PROMPT_CACHING_1H の順です。

変更の前後で寿命別の書き込みを比べる手順は、次のようになります。

手順

寿命の設定変更を数字で検証する

  1. 1

    変更前の分布を取る

    数日分の api_request から、write_5m と write_1h の合計を出しておきます。

  2. 2

    設定を1つだけ変える

    たとえば promptCacheTtl を 1h にします。サブエージェント側は触らず、効いた場所を切り分けます。

  3. 3

    同じ集計を回して比べる

    write_1h の比率が動いたか、read の倍率が上がったかを見ます。

query_source で絞ると、メインの会話とサブエージェント、圧縮処理などの補助リクエストを分けて見られます。属性の説明にある値は repl_main_thread、compact、サブエージェントの名前などです。主会話だけ1時間にしたはずなのに、別の経路に1時間書き込みが出ていれば、設定の効く範囲を取り違えているサインです。

メトリクスのtoken.usageで寿命別が見えない理由

claude_code.token.usage カウンターの type 属性は、input、output、cacheRead、cacheCreation の4値です。キャッシュ書き込みは cacheCreation の1つにまとまり、5分と1時間の区別はありません。今回加わったのは api_request イベントの属性だけで、メトリクス側の型は増えていません。

Prometheus系のダッシュボードで cacheCreation を眺めても寿命別の比率が出ないのは、この仕様のためです。寿命別に見たいときは、メトリクスではなくログ側のイベントを集計します。メトリクスは model や skill.name などの切り口で全体の傾向を追うのに向き、寿命の内訳はイベントで補う、という分担になります。

集計クエリの具体例

ログ基盤がSQLで引ける場合の例です。テーブル名と列名は基盤ごとに違うので、読み替えてください。

-- 例: モデルとquery_sourceごとの寿命別書き込み(擬似SQL)
SELECT model, query_source,
       SUM(cache_creation_5m_tokens) AS write_5m,
       SUM(cache_creation_1h_tokens) AS write_1h,
       SUM(cache_read_tokens)        AS read
FROM   api_request_events
WHERE  event_timestamp >= now() - interval '7 days'
GROUP  BY model, query_source
ORDER  BY write_1h DESC

model と query_source で割ると、1時間書き込みがどのモデルのどの経路に偏っているかが一覧で見えます。単価はモデルで違うため、モデルをまたいだ合算は避けます。

5分と1時間の損益分岐を数字で見る

基本入力単価を1、キャッシュする前置き部分をNトークンとして、倍率だけで比べます。読み取りは標準の0.1倍で計算します。

  • 4分間隔で6回リクエストが続く場合: 5分の寿命は、最初の書き込み1.25Nに読み取り5回の0.5Nを足した1.75Nです。読み取りのたびに寿命が延びるので、書き直しは起きません。1時間の寿命は2N+0.5Nで2.5Nとなり、5分のほうが安く済みます
  • 6分の空きが1回挟まる2回のリクエスト: 5分の寿命は期限切れで書き直しになり、1.25N×2で2.5Nです。1時間の寿命は2N+0.1Nで2.1Nとなり、こちらが安くなります
  • 10分間隔で6回続く場合: 5分の寿命は毎回書き直しで7.5N、1時間の寿命は2N+0.5Nで2.5Nです。差は3倍に開きます

間隔が5分を一度でも超えるなら、1時間書き込みが元を取れる可能性が出てきます。逆に、間隔がずっと5分以内なら1時間書き込みは割高です。寿命別の書き込みと読み取りの倍率を並べれば、自分のセッションがどちらの型かを実データで判定できます。

読み取りの倍率がモデルで違う点にも注意が要ります。Claude Opus 5.5とClaude Sonnet 5.5では0.05倍、Claude Fable 5.1とClaude Mythos 5.1では0.025倍です。読み取りが安いモデルほど、一度書いたキャッシュを何度読めるかの価値は高く、1時間書き込みの2倍という上乗せも読み取り回数で回収しやすくなります。上の3例は標準の0.1倍で計算しているため、使うモデルの倍率に置き換えて試算し直してください。

他の計測との役割分担

同じキャッシュの読み書きでも、見る手段によって粒度が違います。

見たいもの向く手段
組織全体の寿命別の書き込み量向く手段OpenTelemetryの api_request イベント(この記事)
1リクエストごとの読み書きを手元で確認向く手段modの turn.step(Claude Code modのturn.stepでキャッシュの読み書きを表示する)
入力トークンの合計をGenAI規約に合わせる向く手段input_tokens と cache_read_tokens と cache_creation_tokens の合算(OpenTelemetryの入力トークンの換算)

入力トークンの合算では、寿命別の2属性を足し直す必要はありません。合計は従来の cache_creation_tokens で足りるためです。

つまずきやすい点

  • バージョンが古いと属性が付かない。v2.1.299以前のクライアントが混ざる環境では、集計に欠損が出る。v2.1.300の変更全体はリリースノートで追える
  • メトリクスだけを有効にしていても出ない。イベントは OTEL_LOGS_EXPORTER の設定で届く
  • メトリクスの claude_code.token.usage では寿命別に見えない。理由は前の「メトリクスのtoken.usageで寿命別が見えない理由」の節にある
  • Bedrockなどサードパーティ経由での値の出方は、ページに説明がない。0と欠損は受信側で区別して扱う

まとめ

寿命別の2属性は、キャッシュの設定を変えたあとに、効いたかどうかを数字で確かめるための材料です。まず自分の環境で write_1h の比率を出し、設定変更の前後で比べてください。合計との一致は、新しい2属性の説明が属性一覧に無いため、実データでの突き合わせが前提になります。

この記事を共有:XはてブLinkedIn