HTTPキャッシュ有効期限計算
応答ヘッダーを入力して、キャッシュが「新鮮」でいられる期間(鮮度有効期間)と、経過した時間(現在の Age)、残りの鮮度を求めます。
このツールが計算するもの
HTTP のキャッシュ(ブラウザや CDN などが応答を保存して再利用する仕組み)の規格 RFC 9111 のうち、鮮度(freshness)の計算だけを扱います。応答を保存してから、検証せずに再利用してよいかどうかを決める部分です。検証(ETag・If-Modified-Since・304)、Vary、リクエスト側の Cache-Control は扱いません。
鮮度有効期間と現在の Age の違い
- 鮮度有効期間:その応答が「新鮮」でいられる長さです。応答に書かれた指示(Cache-Control や Expires)で決まり、時間が経っても変わりません。
- 現在の Age:その応答が作られてから今までに経過した時間です。時間が経つほど増えます。
- 新鮮かどうか:鮮度有効期間が現在の Age より大きいときだけ新鮮です(等しいときは古いと扱います)。
- 残りの鮮度 = 鮮度有効期間 − 現在の Age。
鮮度有効期間の優先順位
RFC 9111 の 4.2.1 にもとづき、次の順に最初に見つかったものを使います。
| 順 | 共有キャッシュ(CDN・プロキシ) | プライベートキャッシュ(ブラウザ) |
|---|---|---|
| 1 | s-maxage | (s-maxage は使いません) |
| 2 | max-age | max-age |
| 3 | Expires − Date | Expires − Date |
| 4 | どれもなければ、明示的な有効期限なし | 同左 |
- max-age があると、Expires は無視します。 共有キャッシュで s-maxage があると、max-age と Expires を無視します(5.3)。
- 同じ指示が何度も書かれているときは、最初のものを使います(RFC 9111 が認める扱いの一つです)。
- 値が整数でない、または引用符で囲まれている(RFC 9111 は送信側に引用符つきの形を禁じています)max-age・s-maxage は、不正な値として古い(鮮度有効期間 0)と見なします。値が 2,147,483,648 を超えるときは、2,147,483,648 として扱います(1.2.2)。
- Expires が
0、または実在しない日付のときは、すでに期限切れとして扱います(5.3)。 - 明示的な有効期限がないとき、ヒューリスティック(Last-Modified からの推定など)は計算しません。 鮮度有効期間は実装によって決まります(Last-Modified の間隔の 10% は、RFC が挙げる典型例で、規定値ではありません)。
現在の Age の計算
RFC 9111 の 4.2.3 の式を使います。
- 見かけの Age = max(0, 受け取った日時 − Date)
- 受け取った時点の Age = max(見かけの Age, Age ヘッダー + 応答の遅延)
- 現在の Age = 受け取った時点の Age + 受け取ってから経過した時間
このツールは、リクエストを送った時刻を入力しないため、応答の遅延(リクエストを送ってから応答を受け取るまでの時間)を 0 として計算します。 遅延が大きい通信では、実際の現在の Age より小さく計算されることがあります。RFC は、Age ヘッダーの値に遅延を足した値だけを使ってもよいとしています。
入力のきまり
- 日付は IMF-fixdate(例:
Sun, 06 Nov 1994 08:49:37 GMT)と、UTC の2026-10-21 07:28:00の形で入力します。すべて UTC(GMT)で、タイムゾーンは扱いません。範囲は 1900〜2100 年です。曜日の名前は、日付と合っているか確かめません。 - RFC 850 形式・asctime 形式は、HTTP では受信側が受け付けるべき形式として認められていますが、このツールでは非対応です。(「HTTP で無効」という意味ではありません。IMF-fixdate に直して入力してください。)
- Date が空欄のときは、入力した「応答を受け取った日時」を Date の代わりに使います。RFC 9110 は、Date のない応答をキャッシュや転送する受信側が、受信した時刻を Date として追加する、と定めています。受け取った日時も空欄なら、Date を使う計算(Expires − Date、見かけの Age)はできません。ブラウザの現在時刻を、自動では使いません。 「今の日時を入力」ボタンを押したときだけ、確認する日時の欄に入ります。
- 確認する日時は、応答を受け取った日時以降にしてください。
Cache-Control のほかの指示
計算には使いませんが、再利用についての注意として表示します。
- no-store:保存してはならない。 private:共有キャッシュは保存してはならない(ブラウザは保存してよい)。
- no-cache(引数なし):新鮮でも、検証せずに再利用してはならない。
- must-revalidate:古くなったあとは、検証せずに使ってはならない。 proxy-revalidate:同じ意味で、プライベートキャッシュには適用されない。
- public:保存してよいと明示する。
- immutable(RFC 8246)、stale-while-revalidate・stale-if-error(RFC 5861)は、RFC 9111 の範囲外です。認識しますが、計算には使いません。
計算例
| 入力 | 結果 |
|---|---|
| max-age=3600、Age なし、受け取ってから 1,800 秒後 | 鮮度有効期間 3,600 秒、現在の Age 1,800 秒、残り 1,800 秒(新鮮) |
| 同じ条件で、ちょうど 3,600 秒後 | 現在の Age 3,600 秒。鮮度有効期間と等しいので、古い |
| max-age=3600、Age=600、受け取った直後 | 現在の Age 600 秒、残り 3,000 秒 |
| 共有キャッシュで s-maxage=60, max-age=3600 | 鮮度有効期間 60 秒(max-age は無視) |
注意点
- これは規格にもとづく計算です。実際のブラウザや CDN は、規格どおりに動くとは限りません。 強制再読み込みなどの操作や、CDN 独自の設定で、結果が違うことがあります。特定の製品の動作は保証しません。
- ヒューリスティック、検証、Vary、リクエスト側の指示、複数のキャッシュの合算は扱いません。
よくある質問
max-age と Expires の両方があるとどうなりますか?
max-age があると、Expires は無視されます(RFC 9111 の 5.3)。
s-maxage はブラウザにも効きますか?
s-maxage は共有キャッシュ用の指示です。プライベートキャッシュ(ブラウザ)では使いません。
Age ヘッダーとは何ですか?
応答が、送信元で作られたり再検証されたりしてから経過した秒数を、途中のキャッシュが書き込む値です。このツールでは、現在の Age の計算に使います。
時刻を調べるには?
UNIX 時間・日時変換や、Cron 式・次回実行日時計算も使えます。