Codexの利用量とPrompt Cachingの見方

Codexの利用量とPrompt Cachingの見方

Codex を ChatGPT plan で重めに使っていると、ローカルログ上は非常に大きな token 数に見える。

ただし、ChatGPT plan の Codex 利用と OpenAI API 課金は同じものではない。ChatGPT plan 側では agentic usage limit と rate limit で制御され、API 側では input / cached input / output の token 単価で課金される。

このメモでは、ローカルの ~/.codex から次を確認する。

  • 月次でどのくらい使っているか
  • cached input がどの程度効いているか
  • 短文脈と長文脈の割合
  • API 課金に近い概算を見る時の注意点

ローカルログの構造

Codex CLI は ~/.codex 配下に session JSONL と SQLite のローカル状態を持つ。

月次統計の主データとして使うのは session JSONL の event_msg / token_count event である。

現在の JSONL では、usage は top level ではなく payload.info.last_token_usage に入っている。

jq -c '
  select(.type == "event_msg"
    and .payload.type == "token_count"
    and .payload.info.last_token_usage? != null)
  | {
      timestamp,
      model_context_window: .payload.info.model_context_window,
      usage: .payload.info.last_token_usage
    }
' ~/.codex/sessions/2026/05/01/*.jsonl

last_token_usage は次の値を持つ。

field意味
input_tokensその呼び出しでモデルへ入った入力 token
cached_input_tokensinput_tokens のうち prompt cache hit した input token
output_tokens出力 token
reasoning_output_tokensreasoning 用の出力 token
total_tokensローカルログ上の合計

SQLite の ~/.codex/state_5.sqlite は、thread 一覧や UI 表示に近い概算を見るには便利。 一方、API 課金に近い概算では、呼び出し単位の last_token_usage を積み上げる方が良さそう。

月次集計の境界

月次集計では、ディレクトリ名だけで月を切らない。

5月末に開始した session は、6月に入ってからも ~/.codex/sessions/2026/05/...jsonl に追記されることがある。そのため、~/.codex/sessions/2026/05 配下を丸ごと合算すると、6月分の token_count event が混ざる。

精度を上げるなら、JSONL event の timestamp で境界を切る。

日本時間の 2026 年 5 月いっぱいを見る場合は、UTC では次の範囲になる。

2026-04-30T15:00:00Z <= timestamp < 2026-05-31T15:00:00Z

Codex のファイル名に出る T23:xx と JSONL 内部の timestamp が 9 時間ずれる場合は、ファイル名側が日本時間相当、JSONL の timestamp が UTC と見て扱う。

2026年5月の実測

2026年5月いっぱいを JSONL event timestamp で切って集計した。

これは OpenAI 側の正式な usage accounting ではない。この端末の Codex session JSONL に残っている token_count event の合算である。

metricvalue
token_count events55,627
input6,942,601,979
cached input6,646,101,064
uncached input296,500,915
output21,977,923
reasoning output7,419,041
logged total6,973,110,454
cached input ratio95.729%
avg input / event124,806
input p50127,113
input p90211,770
input p95223,687
input p99235,734
max input265,348

モデル名は JSONL の session_meta だけでは直接取れないため、state_5.sqlitethreads.rollout_path -> threads.model と JSONL の input_filename を join している。

modeleventsinputcached inputuncached inputoutputtotalcached pct
gpt-5.551,8846,839,599,9806,558,155,264281,444,71620,058,7416,868,141,67195.885%
gpt-5.3-codex-spark3,695102,481,68087,823,61614,658,0641,914,123104,443,40585.697%
ternary-bonsai-8b47505,008115,656389,3524,923509,93122.902%
gpt-5.3-codex115,3116,5288,78313615,44742.636%

API利用だった場合の推定金額

2026-06-02 時点の OpenAI API 価格で概算すると、5月分は約 $5,355.90 になる。

これは ChatGPT plan / Codex plan の請求額ではない。もし同じ token usage を API で実行したら、という換算である。

価格前提:

modelinput / 1Mcached input / 1Moutput / 1M扱い
gpt-5.5$5.00$0.50$30.00公式の gpt-5.5 API 価格
gpt-5.3-codex-spark$1.75$0.175$14.00API 同名価格がないため gpt-5.3-codex 価格で近似
gpt-5.3-codex$1.75$0.175$14.00公式の gpt-5.3-codex API 価格
ternary-bonsai-8b---local model として OpenAI API 換算から除外

主推定では output_tokens を出力側の課金 token として扱う。

保守的推定では、ローカルログの total_tokens - input_tokensoutput_tokens より大きい場合に、その差分を出力側として扱う。これは JSONL の total_tokensinput_tokens + output_tokens が完全に一致しない event があるためである。

modeluncached inputcached inputoutputmain estimateconservative estimate
gpt-5.5281,444,7166,558,155,26420,058,741$5,288.06$5,542.55
gpt-5.3-codex-spark14,658,06487,823,6161,914,123$67.82$68.48
gpt-5.3-codex8,7836,528136$0.02$0.02
total296,111,5636,645,985,40821,973,000$5,355.90$5,611.06

gpt-5.5 には long context の追加料金条件があるが、今回の input_tokens 最大値は 265,348 で、追加料金しきい値の 272K を超えていない。そのため、この概算では long context uplift は加えていない。

短文脈と長文脈

短文脈/長文脈は、固定の token 数ではなく、input_tokens / model_context_window の比率で見る。

モデルごとに context window が違うため、絶対 token 数だけで分類すると判断が歪む。

このメモでは次の分類にした。

band条件
shortinput_tokens / model_context_window < 25%
medium25% <= input_tokens / model_context_window < 50%
long50% <= input_tokens / model_context_window < 80%
near limit80% <= input_tokens / model_context_window

2026年5月の分類は次の通り。

bandeventsinputcached inputuncached inputoutputtotalcached pct
short <25%11,629411,524,447347,091,32864,433,1194,793,637424,848,63684.343%
medium 25-50%16,6801,599,307,9411,515,066,31284,241,6296,833,8301,606,141,77194.733%
long 50-80%20,4703,414,385,6213,303,882,240110,503,3817,802,0243,422,187,64596.764%
near limit >=80%6,8481,517,383,9701,480,061,18437,322,7862,548,4321,519,932,40297.540%

long + near limit は event 数で約 49.1%、input token 量で約 71.0% だった。

short は event 数で約 20.9%、input token 量で約 5.9% に留まる。

この月の Codex 利用は、回数では中長文脈が中心で、token 量では明確に長文脈側が支配的だった。

API換算で見る時の考え方

API の料金表では、少なくとも次を分ける。

  • uncached input
  • cached input
  • output

cached_input_tokensinput_tokens の内数として扱う。

uncached_input = input_tokens - cached_input_tokens

estimated_cost =
  uncached_input * input_price
  + cached_input * cached_input_price
  + output_tokens * output_price

reasoning output token は output 側の一部として見る。ローカル JSONL では reasoning_output_tokens として見えるが、料金計算ではモデルの出力 token として扱われる前提で概算する。

注意点:

  • ChatGPT plan の Codex 利用は API billing ではない
  • API 価格は変わる
  • Codex plan 側の usage limit と API の token billing は同じ尺度ではない
  • local log は手元環境の概算で、OpenAI 側の正式な請求データではない

cached inputとは何か

cached input は、最終回答や HTTP response をキャッシュしているという意味ではない。

LLM の推論は大きく分けると、入力 prompt を読む prefill と、出力 token を生成する decode に分かれる。

長い prompt では prefill が重い。各 transformer layer は入力 token から attention 用の key / value tensor を作る。prompt caching は、同じ prompt prefix が再び来た時に、この prefix 部分の key / value tensor を再利用する仕組みと考えると分かりやすい。

request A:
  stable prefix + new tail
  -> stable prefix の KV を作る
  -> cache に載る

request B:
  same stable prefix + another tail
  -> stable prefix の KV を再利用
  -> new tail 以降だけ通常どおり処理

GPU 的には、同じ prefix を毎回 transformer に通して key / value を再計算する負荷を避けられる。出力 token の生成そのものは毎回必要なので、output が無料になるわけではない。

Codexで効きやすい理由

Codex は prompt caching が効きやすい構造を持つ。

毎回の request prefix に、比較的安定した情報が大量に入るためである。

  • system / developer instructions
  • tool 定義
  • MCP / connector / dynamic tool schema
  • sandbox / approval / workspace context
  • AGENTS.md
  • 直前までの会話履歴や要約
  • 同じ repository で繰り返し使う方針や制約

この安定した prefix の後ろに、新しい user request や tool result が足される。

そのため、長い session では input token の大半が cached input になることがある。見かけ上の input token は大きくても、実際の prefill 計算と API 換算コストは uncached input より低くなる。

ただし、cache は意味が同じなら効く、というものではない。token 列の prefix が一致する必要がある。

先頭側に毎回変わる timestamp、random ID、長い一時ログ、順序が揺れる context を入れると、その位置以降の cache hit が落ちる。

迷惑な使い方かどうか

Codex は、長い coding task、大きな codebase、agentic な調査、tool execution を想定した product である。

大きな context を持つ session や長時間 task は、per message の消費が大きくなる。これは異常ではなく、Codex の設計対象に入っている。

見るべきなのは、token 数そのものより次である。

  • plan 側の limit に実際に当たっているか
  • rate_limit_reached_type が出ているか
  • 複数プロセスで無制御に並列していないか
  • limit 回避のためにアカウントや環境を分散していないか
  • 無限ループや unattended automation になっていないか

ローカルログで rate limit の雰囲気を見る例:

find ~/.codex/sessions/2026/05 -type f -name '*.jsonl' -print0 |
  xargs -0 -n 100 perl -ne '
    while (/"rate_limit_reached_type":(null|"[^"]+")/g) {
      print "$1\n";
    }
  ' |
  sort |
  uniq -c

null 以外が頻繁に出るなら、plan 側の制御に当たっている。

null のままであれば、少なくとも OpenAI 側の制御から見て、その時点では許容範囲にいると考えてよい。

参考