TTLとは、キャッシュの有効期限と仕組み

著者: IT Sectr 公開日: 2026-06-13 読了時間: 8 分

TTL(Time To Live)は、データが有効と見なされる最大時間を決定するパラメータです。TTLが期限切れになると、レコードは古い(stale)とマークされ、削除または更新される必要があります。Mozilla Developer Network(2026)によると、TTLメカニズムはCache-Control: max-ageヘッダーによるHTTPキャッシングの基盤であり、ネットワークリクエストを最適化するためにすべての最新ブラウザとモバイルアプリケーションで使用されています。

重要ポイント

  • TTL(Time To Live)— レコードの有効期限。その後データは古いと見なされ更新が必要
  • バランス— 短いTTLは最新のデータを提供するがキャッシュ効率が低下。長いTTLはパフォーマンスを向上させるが古くなるリスクがある
  • HTTPキャッシング— Cache-Control: max-ageヘッダーがサーバー応答のTTLを秒単位で設定
  • DNSレコード— TTLはリゾルバがドメインのIPアドレスをキャッシュする時間(60〜86400秒)を決定
  • モバイルアプリ— TTLはAPI応答、画像、セッションデータのキャッシュに使用

TTLとは

TTL(Time To Live)は、データが無効と見なされるタイムスタンプまたは間隔です。キャッシングの文脈では、TTLはレコードがソースから再取得される必要がある前にキャッシュに保存できる時間を決定します。ネットワークプロトコルでは、TTLはパケットの有効期間を制限し、無限ルーティングを防ぎます。

TTL値は常にミリ秒、秒、分、時間の単位で表されます。設定された時間が経過すると、レコードはキャッシュから削除されるか、古いとしてマークされます。古いレコードへの次のリクエストでは、システムは後続の更新(stale-while-revalidate)とともに古いデータを返すか、新しいデータが取得されるまでリクエストをブロックできます。

TTLの選択は常にデータの新鮮さとパフォーマンスのトレードオフです。短すぎるTTL(1〜5秒)はアプリケーションに頻繁なネットワークリクエストを強制し、キャッシングの利点を無効にします。長すぎるTTL(数時間〜数日)はユーザーに古い情報を表示するリスクを高めます。最適な値はデータの種類によって異なります:為替レート—秒、天気—分、APIバージョン—時間。

TTLとキャッシュ無効化

TTLは受動的な無効化です:データは一定期間後に自動的に削除されます。代替案は能動的な無効化で、データソースが変更をキャッシュに通知します(WebSocketメッセージやプッシュ通知など)。TTLによる受動的な無効化は実装が簡単ですが、即時の新鮮さを保証しません。能動的な無効化はより複雑ですが、TTLに固有の遅延なしにデータを最新に保つことができます。

TTLの仕組み

TTLメカニズムは2つの方法で実装できます:絶対有効期限(absolute expiration)と相対有効期限(relative expiration)です。絶対有効期限では、レコードは無効になる特定の時間を保存します。相対有効期限では、レコードの作成時間とTTLが間隔として記録され、creationTime + TTL > currentTimeを計算してチェックが行われます。

キャッシュへの各リクエストで、システムは各レコードのTTLをチェックします。TTLが期限切れの場合、データは削除されるか古いとしてマークされ、リクエストはソースに転送されます。TTLチェックを最適化するために、スケジュールされたクリーンアップ(期限切れレコードの定期的な削除)や遅延クリーンアップ(レコードにアクセスしたときのみ削除)を使用できます。遅延クリーンアップは、キャッシュ全体をスキャンするためのバックグラウンドスレッドを必要としないため、メモリ効率が向上します。

分散システムでは、TTLは自動的な競合解決にも使用されます。たとえば、2つのサーバーが同じキーに異なる値を同時に書き込んだ場合、後のTTLを持つレコードが優先されることがあります。Amazon DynamoDBはテーブル内の古いレコードを自動削除するためにTTLを使用します—これは手動管理を必要としない組み込み機能です。

古いデータの読み取り戦略

TTLが期限切れになったときのパフォーマンスを向上させるために、古いデータの読み取り戦略が使用されます。Stale-while-revalidate—すぐにクライアントに古いデータを返し、同時にバックグラウンド更新を開始します。Stale-if-error—ソースが一時的に利用できない場合、古いデータを返します。Cache-Aside(Lazy Loading)—キャッシュミス時、ソースからデータを読み込み、新しいTTLでキャッシュに保存してからクライアントに返します。各戦略はデータの一貫性要件に基づいて選択されます。

データキャッシングにおけるTTL

モバイルアプリケーションでは、TTLはキャッシュ管理の主要なメカニズムです。TTLがアプリケーションの動作とユーザーエクスペリエンスを決定する主なシナリオを見てみましょう。

HTTP応答のキャッシング

HTTPプロトコルはCache-Controlヘッダーを通じて組み込みのTTLメカニズムを提供します。max-ageディレクティブはTTLを秒単位で設定します:Cache-Control: public, max-age=3600は応答を1時間キャッシュできることを意味します。追加のディレクティブs-maxage(共有キャッシュ、例:CDN用)とstale-while-revalidateはより細かい制御を提供します。TTLがexpiresヘッダーと一致する場合、より近代的なHTTP/1.1標準としてmax-ageが優先されます。

データの種類推奨TTL根拠
天気10〜30分予報は頻繁に更新されない
為替レート15〜60秒高い変動性
ニュースフィード2〜5分新鮮さとパフォーマンスのバランス
ユーザープロフィール5〜30分セッション中にほとんど変更されない
商品リスト10〜60分価格は毎秒変わらない
静的リソース1〜24時間URLまたはETagでバージョン管理

画像のキャッシング

画像の場合、コンテンツがほとんど変更されないため、TTLは数日に達することがあります。ただし、モバイルアプリケーションはハイブリッドアプローチをよく使用します:プレビューには短いTTL(30分—フレームの新鮮さ)、フルサイズ画像には長いTTL(7日間)。HTTPヘッダーCache-Control: immutableを持つ画像はTTLが期限切れになるまで再リクエストされるべきではありません—これはRFC 8246で提案された静的リソースの最適化です。そのような画像は、アプリケーションの関与なしにOSレベル(URLCache、OkHttp Cache)でキャッシュされます。

ネットワークプロトコルにおけるTTL

ネットワークでは、TTLはキャッシングではなくパケットの有効期間を制限するために使用されます。各IPパケットにはTTLフィールド(8ビット)が含まれ、各ルーターによって1ずつ減少します。TTLが0に達すると、パケットは破棄され、送信者はICMP Time Exceededメッセージを受け取ります。これにより、ネットワークループ中の無限ルーティングが防止されます。

DNSにおけるTTL

DNSレコードには、リゾルバ(ISP DNSキャッシュなど)が権威サーバーに問い合わせずにレコードを保存できる時間を決定するTTLがあります。一般的な値:頻繁に変更されるレコードには300秒(5分)、安定したドメインには86400秒(24時間)。CDNサービスは障害時の迅速なトラフィック再ルーティングのために低いTTL(60〜300秒)を設定することが多く、静的ドメインは最大7日間のTTLを持つことができます。サーバー移行時には、最初にTTLを60秒に下げて(移行の48時間前)、変更が迅速に伝播するようにすることをお勧めします。

セッションとトークンにおけるTTL

モバイルアプリケーションでは、TTLはセッションとアクセストークンの管理に使用されます。JWTトークン(JSON Web Tokens)にはexp(有効期限)フィールドが含まれ、これは絶対的なUnix有効期限時間です。期限切れ後、更新トークンを使用して再認証なしで新しいアクセストークンを取得します。アクセストークンのTTLは通常1〜24時間、更新トークンのTTLは7〜30日です。これはセキュリティ(短いTTLは漏洩リスクを低減)とUX(長いTTLは再ログインの頻度を低減)のバランスです。

TTL選択戦略

TTLの選択は、データの種類、鮮度SLA、再リクエストのコストに依存するエンジニアリング上の決定です。主な戦略を見てみましょう。

固定TTL

最も単純なアプローチ—すべてのレコードが同じTTLを持ちます。たとえば、すべてのAPI応答を5分間キャッシュします。利点:実装の単純さと予測可能な動作。欠点:異なるデータ種類の異なる変更頻度を考慮しません。固定TTLは、すべてのレコードが同じ「新鮮さ」を持つ均一なデータに適しています—たとえば、1つの取引所での暗号通貨レート。

適応型TTL

TTLはデータの動作に基づいて動的に変化します。たとえば、レコードがサーバー上でほとんど更新されない場合、TTLは増加し、頻繁に更新される場合は減少します。実装はHTTP応答ヘッダーを使用できます:Ageヘッダー(応答がキャッシュにあった秒数)とDateヘッダーにより、残りの有効期間を計算できます。適応型TTLはヒット率を向上させますが、クライアントに追加のロジックが必要です。

確率的TTL期限切れ

Probabilistic Early Expiration(PEE)—指定された範囲内でTTLをランダムに選択する技法です。これにより、多数のリクエストが同時に期限切れになり、すべてのクライアントが同時にソースにアクセスする「スランディングハード」(thundering herd)効果を防ぎます。PEEは特にCDNと高負荷キャッシュに有用です:300秒の単一TTLの代わりに、240〜360秒のランダムな値を使用して、ソースへの負荷を均等に分散します。

TTLコード例

絶対有効期限を使用してKotlinでTTL付きキャッシュの実装を見てみましょう。各レコードは作成時間を保存し、読み取り時にTTLが期限切れかどうかがチェックされます。

kotlin
class TtlCache<K, V>(
    private val defaultTtlMs: Long = 300000L
) {
    private data class Entry<V>(
        val value: V,
        val createdAt: Long = System.currentTimeMillis()
    )

    private val map = ConcurrentHashMap<K, Entry<V>>()

    fun get(key: K): V? {
        val entry = map[key] ?: return null
        if (isExpired(entry)) {
            map.remove(key)
            return null
        }
        return entry.value
    }

    fun put(key: K, value: V, ttlMs: Long = defaultTtlMs) {
        map[key] = Entry(value, createdAt = System.currentTimeMillis() + ttlMs)
    }

    private fun isExpired(entry: Entry<*>): Boolean {
        return System.currentTimeMillis() > entry.createdAt
    }

    fun cleanup() {
        map.entries.removeIf { isExpired(it.value) }
    }
}

Entryクラスは値と作成時間+TTL(絶対有効期限)を保存します。getメソッドは各アクセスで有効期限をチェックします(遅延クリーンアップ)—期限切れのレコードはアクセスが試みられたときのみ削除されます。cleanupメソッドはバックグラウンドスレッドから定期的に呼び出して、すべての古いレコードを一括削除できます。ConcurrentHashMapはキャッシュ全体をロックせずにスレッドセーフを提供します。

例:iOSでのAPI応答キャッシュ用TTL

iOSでは、TTL付きキャッシングにmemoryCapacityとdiskCapacityの設定でURLCacheを使用すると便利です。ただし、URLCacheはリクエストごとに個別のTTLをサポートしていません。TTLサポート付きのカスタムNSCacheラッパーを考えてみましょう。

swift
final class ApiResponseCache {
    private var cache = NSCache<NSString, CacheEntry>()

    func getResponse(for url: URL) -> Data? {
        guard let entry = cache.object(forKey: url.absoluteString as NSString)
            else { return nil }
        guard entry.expirationDate > Date() else {
            cache.removeObject(forKey: url.absoluteString as NSString)
            return nil
        }
        return entry.data
    }

    func storeResponse(data: Data, for url: URL, ttl: TimeInterval) {
        let entry = CacheEntry(data: data, expirationDate: Date().addingTimeInterval(ttl))
        cache.setObject(entry, forKey: url.absoluteString as NSString)
    }
}

final class CacheEntry: NSObject {
    let data: Data
    let expirationDate: Date
}

この実装では、NSCacheがスレッドセーフなストレージとして使用されます。CacheEntryにはDataとexpirationDateが含まれます。getが呼び出されると、時間が期限切れかどうかがチェックされ、期限切れの場合はレコードが削除されてnilが返されます。TTLはTimeIntervalを介して秒単位で設定され、URLごとに異なる場合があります:API応答の一般的な値は、動的コンテンツで120秒、静的データで3600です。

よくある質問

TTLとデータの有効期限の違いは何ですか?

技術的には、TTLと有効期限は同じものです:データが無効と見なされる時間間隔。違いは文脈にあります:TTLという用語はIT(キャッシング、ネットワーキング、DNS)で使用され、「有効期限」はビジネスロジック(プロモコード、サブスクリプション)でより頻繁に適用されます。実装では、両方のメカニズムは同じです—現在時刻と有効期限の比較。

最適なTTLを選択するには?

最適なTTLは経験的に選択されます。方法:控えめな値(30〜60秒)から始め、古いデータに関する苦情が出るまで徐々に増やします。キャッシュヒット率を監視します:70%未満の場合はTTLが短すぎます。SLAを考慮します:金融データのTTLは1秒、ニュースは5分、プロフィールは30分です。

HTTPでTTLが期限切れになるとどうなりますか?

max-ageが期限切れになると、ブラウザまたはモバイルアプリケーションは応答を古いと見なします。同じURLへの次のリクエストで、クライアントはIf-None-Match(ETag)またはIf-Modified-Sinceヘッダーとともにリクエストを送信します。データが変更されていない場合、サーバーは応答本文なしで304 Not Modifiedを返し、TTLが更新されます。変更された場合、サーバーは新しいデータと新しいCache-Controlとともに200を返します。

TTLは無限にできますか?

技術的には、TTLは非常に大きくできます(max-age=31536000 — 1年)が、これが正当化されることはほとんどありません。静的リソースでさえ変更される可能性があり、クライアントはTTLが期限切れになるまでそれを知りません。長いTTLとバージョン管理されたURL(style.css?v=2)を使用することをお勧めします:ファイルが変更されるとURLが変更され、古いキャッシュは自動的に時代遅れになります。

TTLとLRU、FIFOの関係は?

TTLと退出戦略(LRU、FIFO)は異なる問題を解決します。TTLはデータがいつ無関係になるかを決定します—これは時間的基準です。LRUとFIFOはキャッシュがいっぱいになったときにどのデータを削除するかを決定します—これは空間的基準です。これらは組み合わせることができます:TTLが期限切れになった場合、またはキャッシュがいっぱいになった場合(LRU/FIFOによる)、レコードは削除されます。本番システムでは、両方のメカニズムが連携して動作します。

まとめ

  • TTL(Time To Live)— レコードの有効期限。その後データは古いと見なされ更新が必要
  • 絶対有効期限— レコードは正確な有効期限を保存。相対有効期限— 作成時間+間隔
  • バランス— 短いTTLはキャッシュ効率を低下、長いTTLは古いデータのリスクを増加
  • HTTP Cache-Control— max-ageは古いモードのサポートとともにサーバー応答TTLを秒単位で設定
  • DNS解決— 60〜86400秒のTTLはドメインのIPアドレスがキャッシュされる時間を決定
  • 戦略— 固定、適応型、確率的TTLがデータ種類に応じて適用される
  • 使用 完全なキャッシュライフサイクル管理のためにLRU/FIFOとTTLを併用

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください