Prompt cachingは30分と12時間のどちら?人工10時刻列で入力料金を比較

長い共通指示を20分おきに使う処理と、1時間おきに使う処理では、30分と12時間のprompt cacheの選び方が変わります。そこで、10,000 visible input tokensの固定prefixを送る人工時刻列10件を標準Pythonで計算し、cacheなし・30分・12時間のwrite、read、ordinary inputを比べました。
結論は、頻繁な再利用では30分、30分を超える間隔で3回以上使う例では12時間が候補になった一方、単発・60分2回・12時間超・prefix変更ではcacheなしの方が小さい例があった、です。12時間を選ぶだけで安くなるわけではありません。
ただし、これは公式の料金規則を人工時刻へ適用した理想的なeligible入力料金です。実API、cache hit、請求、レイテンシは測っていません。output、各回で変わる入力、tool料金、税なども合計していないため、請求総額の比較ではありません。
公式仕様と今回の計算を分ける
2026年10月20日の公式changelogは、Responses APIで12時間のprompt cachingを選べるようになり、12時間writeは通常入力の2.5倍になると案内しています。Prompt cachingガイドで今回使った条件を確認しました。
| 公式説明として確認した条件 | 今回の扱い |
|---|---|
| GPT-5.6以降は最低1,024 visible input tokens | 全fixtureを10,000 tokensに固定 |
| 30m writeは通常入力の1.25倍 | write 1回を1.25として加算 |
| 12h writeは通常入力の2.5倍 | write 1回を2.5として加算 |
| readは通常0.1倍、GPT-6.1 Solは0.05倍 | 2つのprofileを別々に計算 |
| 30m readは少なくともread時刻+30分までcoverageを更新 | keyごとのexpiryを更新 |
12h coverageのreadは max(existing expiry, read時刻+30分) |
12時間時計自体は再始動させない |
| minimum lifetimeは実KV再利用や低レイテンシを保証しない | 実hit・速度・請求の結果とは書かない |
| OpenAIがminimumより長く保持する場合があり、12hは削除期限ではない | minimum終了後の追加保持は仮定せず、新writeとしてモデル化 |
30分・12時間はwriteの合計rateで、通常入力料金へさらに加えるsurchargeではありません。料金は公式pricingのStandard・短いcontext欄も照合しました。
検証条件:APIを呼ばず人工時刻だけを動かす
2026年10月23日、Windows上のPython 3.14.2で計算しました。追加package、API key、外部接続、費用はありません。各イベントは同じ10,000-token prefixを使い、AからBへ変わるfixtureだけ別cache stateとして扱います。
料金換算は次の式です。通常入力1回分のprefix料金を1としています。
normalized equivalents
= ordinary回数
+ 30m write回数 × 1.25 または 12h write回数 × 2.5
+ read回数 × 0.1 (GPT-6.1 Solだけ0.05)
expiryと完全に同じ時刻の扱いは今回確認できていません。fixtureでは0→30分や0→720分を避け、計算コードも完全一致をエラーにします。これは公開APIがその時刻でエラーになるという意味ではなく、未確認の境界を結果へ混ぜないための制限です。また、minimum coverage終了後は追加保持を仮定せず新しいwriteとします。公式説明上はより長く保持される場合があるため、終了後のwrite回数は実請求の予測ではありません。
人工10時刻列の結果
次はread 0.1倍のprofileです。W/R/O はwrite、read、ordinaryのイベント数、最後の数字は通常入力1回分を1とした合計です。
| 人工時刻列 | cacheなし O / 換算 | 30m W/R/O / 換算 | 12h W/R/O / 換算 |
|---|---|---|---|
| 単発1回 | 1 / 1.00 | 1/0/0 / 1.25 | 1/0/0 / 2.50 |
| 20分間隔で2回 | 2 / 2.00 | 1/1/0 / 1.35 | 1/1/0 / 2.60 |
| 60分間隔で2回 | 2 / 2.00 | 2/0/0 / 2.50 | 1/1/0 / 2.60 |
| 0・60・120分 | 3 / 3.00 | 3/0/0 / 3.75 | 1/2/0 / 2.70 |
| 20分刻みで5回 | 5 / 5.00 | 1/4/0 / 1.65 | 1/4/0 / 2.90 |
| 12時間内に3回(0・240・600分) | 3 / 3.00 | 3/0/0 / 3.75 | 1/2/0 / 2.70 |
| 12時間超で2回(0・721分) | 2 / 2.00 | 2/0/0 / 2.50 | 2/0/0 / 5.00 |
| A→B→A(0・20・40分) | 3 / 3.00 | 3/0/0 / 3.75 | 2/1/0 / 5.10 |
| 0・600・721分 | 3 / 3.00 | 3/0/0 / 3.75 | 2/1/0 / 5.10 |
| 0・700・729・758分 | 4 / 4.00 | 2/2/0 / 2.70 | 1/3/0 / 2.80 |
20分刻み5回では30分が1.65で、12時間の2.90より小さくなりました。同じread回数ならread rateは共通なので、12時間writeの大きさが残るためです。
一方、0・60・120分の3回では、30分は毎回writeとなって3.75、12時間はwrite 1回とread 2回で2.70でした。60分2回だけなら、12時間も2.60となり、cacheなし2.00を上回ります。長い保持時間の価値は「30分を超えた」だけで決まらず、そのprefixを何回再利用するかまで必要です。
12時間readで12時間時計は戻らない
0・600・721分のfixtureは、最初の12時間writeのexpiryを720分とします。600分のreadでは max(720, 630) なのでexpiryは720分のままです。721分はその後なので新しいwriteになり、合計は2.5 + 0.1 + 2.5 = 5.10でした。
対して0・700・729・758分では、700分のreadがexpiryを730分へ延ばし、729分のreadが759分へ、758分のreadが788分へ延ばします。これは各readの30分refreshを順に適用した結果で、12時間時計を12時間ずつ再始動した結果ではありません。
この違いを無視し「12時間内に1度読めば、そこからまた12時間」と実装すると、write回数を過少に見積もる場合があります。
GPT-6.1 Solのread 0.05倍を分離する
GPT-6.1 Solはreadが0.05倍なので、readがある行だけ合計が下がります。write倍率は同じです。
| 人工時刻列 | 30m(0.05 read) | 12h(0.05 read) |
|---|---|---|
| 20分間隔で2回 | 1.30 | 2.55 |
| 0・60・120分 | 3.75 | 2.60 |
| 20分刻みで5回 | 1.45 | 2.70 |
| 12時間内に3回 | 3.75 | 2.60 |
| A→B→A | 3.75 | 5.05 |
モデル名を変えずに0.05だけを採用することはできません。モデルごとの通常入力単価も別なので、この表はGPT-6 LunaのUSD単価と合成していません。
10,000 tokensをGPT-6 Luna Standardへ当てた小さな例
確認時点のGPT-6 Luna Standard・短いcontextは、100万tokensあたり通常入力0.10米ドル、cached input 0.01米ドル、30m write 0.125米ドル、12h write 0.25米ドルです。したがって10,000-token prefixの通常入力1回分は0.001米ドルです。
| 時刻列 | cacheなし | 30m | 12h |
|---|---|---|---|
| 20分刻み5回 | $0.00500 | $0.00165 | $0.00290 |
| 0・60・120分 | $0.00300 | $0.00375 | $0.00270 |
| 12時間超2回 | $0.00200 | $0.00250 | $0.00500 |
これは固定prefix部分だけの算術例です。output、dynamic suffix、tool、画像、272K超の入力条件、処理tier、regional processing、税、為替を含まないため、請求総額や支払実費ではありません。
JSON/CSVと12テストを再現する
コード、fixture、結果、hashをまとめたZIPを新しいフォルダへ展開し、PowerShellで次を実行します。
python .\run_fixtures.py
python -m unittest discover -s tests -p 'test_*.py' -v
最初のコマンドは10 scenarios × 2 read profiles × 3 strategies = 60行の results/schedule_results.json とCSVを作ります。unit testsは、単発、read refresh、60分差、12時間時計の非restart、末尾refresh、prefix変更、GPT-6.1 Sol、1,024未満、境界拒否、決定的出力、不正入力を含む12件です。
公開前に元フォルダで12 testsを3回実行し、各回12/12成功しました。さらに配布ZIPを一時フォルダへ展開し、path、CRC、manifest、SHA-256を検査してから、12 testsとfixture生成を再実行しました。再生成したJSON/CSVは同梱結果とbyte単位で一致しました。
実務への影響と限界:次は実usageを測る
この計算は、同じprefixがeligible lookup boundaryへ一致し、minimum lifetime中は料金上readになる理想条件です。minimum終了後については追加保持を仮定しない単純な状態モデルです。公式ガイドも、minimum lifetimeは毎回の保存KV再利用や低レイテンシを保証せず、12時間が削除期限でもないと説明しています。prefix末尾以降の変動部分、暗黙・明示breakpointの選択、routing、実際の cached_tokens と cache_write_tokens は再現していません。
実運用へ進むなら、まず実際の再利用対象を1,024 visible tokens以上に固定し、次の4項目を小規模に記録します。
- 同じprefix keyのrequest時刻とprefix token数
usage.input_tokens_details.cached_tokens- 30m・12h別のcache write tokens
- input費用とレイテンシの実測値
そのうえで、手元の時刻列を本教材のfixture形式へ置き換え、理想値と実usageの差を見ます。差が大きければ、12時間へ延ばす前にprefixの変化、breakpoint、model、service tierを切り分けます。
本稿は、GPT-5.6 Solの単価変更を記録した旧料金記事の更新ではなく、再利用時刻からwrite/read回数を選ぶ別の問いを扱います。定期処理の実行重複を止めたい場合は、定期タスクの二重実行と文字コード検証が関連します。表紙は概念画像で、検証証拠には数えていません。