title: "期限付き投稿のキャッシュTTLを残り時間以内に収める(JavaScript)"
24時間で消える投稿を表示するサービスでは、元の投稿が消えた後もキャッシュから「公開中」と返してしまうと誤解を招きます。キャッシュの最大TTLを固定値だけで決めず、投稿の残り寿命より短くする方法を整理します。ここでは上流から信頼できる有効期限を受け取れる場合を想定します。
TTLの上限は二つある
キャッシュの通常の上限を5分にしていても、投稿の残り時間が30秒なら、その応答のTTLは30秒以下にします。期限が過ぎているならキャッシュせず、公開中として返しません。
function ttlForExpiringPost({ nowMs, expiresAtMs, maxTtlMs }) {
if (!Number.isFinite(nowMs) || !Number.isFinite(expiresAtMs)) {
throw new TypeError('timestamps must be finite numbers');
}
if (!Number.isFinite(maxTtlMs) || maxTtlMs < 0) {
throw new RangeError('maxTtlMs must be nonnegative');
}
return Math.min(maxTtlMs, Math.max(0, expiresAtMs - nowMs));
}
const nowMs = Date.parse('2026-10-06T10:00:00Z');
const fiveMinutes = 5 * 60 * 1000;
console.assert(ttlForExpiringPost({ nowMs, expiresAtMs: nowMs + 30_000, maxTtlMs: fiveMinutes }) === 30_000);
console.assert(ttlForExpiringPost({ nowMs, expiresAtMs: nowMs + 10 * 60_000, maxTtlMs: fiveMinutes }) === fiveMinutes);
console.assert(ttlForExpiringPost({ nowMs, expiresAtMs: nowMs - 1, maxTtlMs: fiveMinutes }) === 0);
この関数はミリ秒を返します。HTTP の Cache-Control: max-age に使うなら秒へ変換し、端数を切り捨てます。期限が数百ミリ秒先の場合、切り捨て結果は0秒です。切り上げると期限後まで表示する可能性があります。
有効期限が分からない場合
上流データが投稿時刻や失効時刻を保証しないなら、正確な残り時間を推測してはいけません。短い固定TTLを使い、再取得時に投稿がまだ公開されているか確認します。エラー時に古いキャッシュを返す stale-if-error のような設定も、期限付き投稿には慎重に適用します。再取得失敗と「まだ存在する」は別の状態です。
私は公開TikTokアカウントのストーリーと残り時間を表示する TikStories を作っています。この記事のコードは同サービスの内部実装ではなく、期限付きコンテンツ一般を扱うための小さな例です。非公開の投稿や期限切れの投稿を取得する方法ではありません。
境界をテストする
テストでは期限の1ミリ秒前、期限ちょうど、期限の1ミリ秒後を確認します。あわせて、キャッシュ更新中に投稿が削除された場合、取得元が一時的に失敗した場合、サーバー時計がずれた場合の表示文言も分けて確認します。「投稿なし」「取得失敗」「期限切れ」を一つの空配列にまとめると、画面で原因を説明できなくなります。