TTL (Time To Live) — parametr, který určuje maximální dobu, po kterou jsou data považována za aktuální. Po vypršení TTL je záznam označen jako zastaralý (stale) a musí být odstraněn nebo aktualizován. Podle Mozilla Developer Network (2026) tvoří mechanismus TTL základ HTTP cacheování prostřednictvím hlavičky Cache-Control: max-age a používá se ve všech moderních prohlížečích a mobilních aplikacích k optimalizaci síťových požadavků.
Hlavní body
TTL (Time To Live) — je časové razítko nebo interval, po kterém jsou data považována za neplatná. V kontextu cacheování TTL určuje, jak dlouho může být záznam uložen v cache, než je třeba jej znovu vyžádat z původního zdroje. V síťových protokolech TTL omezuje životnost paketu, čímž zabraňuje nekonečnému směrování.
Hodnota TTL je vždy vyjádřena v časových jednotkách: milisekundách, sekundách, minutách nebo hodinách. Po uplynutí nastaveného času je záznam buď odstraněn z cache, nebo označen jako stale (zastaralý). Při následujícím požadavku na zastaralý záznam může systém vrátit zastaralá data s následnou aktualizací (stale-while-revalidate) nebo blokovat požadavek do obdržení čerstvých dat.
Výběr TTL je vždy kompromisem mezi aktualitou dat a výkonem. Příliš krátký TTL (1–5 sekund) nutí aplikaci často provádět síťové požadavky, čímž ruší výhody cacheování. Příliš dlouhý TTL (hodiny/dny) zvyšuje riziko zobrazení zastaralých informací uživateli. Optimální hodnota závisí na typu dat: měnné kurzy — sekundy, počasí — minuty, verze API — hodiny.
TTL je pasivní invalidace: data jsou automaticky odstraněna po uplynutí času. Alternativou je aktivní invalidace, kdy zdroj dat informuje cache o změnách (například prostřednictvím WebSocket zpráv nebo push oznámení). Pasivní invalidace prostřednictvím TTL je jednodušší na implementaci, ale nezaručuje okamžitou aktuálnost. Aktivní invalidace je složitější, ale umožňuje udržovat data v aktuálním stavu bez zpoždění charakteristických pro TTL.
Mechanismus TTL lze implementovat dvěma způsoby: absolutní vypršení (absolute expiration) a relativní vypršení (relative expiration). Při absolutním vypršení záznam ukládá konkrétní čas, kdy se stane neplatným. Při relativním vypršení se zaznamenává čas vytvoření záznamu a TTL jako interval, a kontrola se provádí výpočtem creationTime + TTL > currentTime.
Při každém požadavku na cache systém kontroluje TTL každého záznamu. Pokud TTL vypršelo, data jsou odstraněna nebo označena jako stale a požadavek je směrován ke zdroji. Pro optimalizaci kontroly TTL lze použít scheduled-cleanup (periodické odstraňování všech prošlých záznamů) nebo lazy-cleanup (odstraňování pouze při přístupu k záznamu). Lazy-cleanup je efektivnější z hlediska paměti, protože nevyžaduje vlákno na pozadí pro skenování celé cache.
V distribuovaných systémech se TTL také používá pro automatické řešení konfliktů. Například, pokud dva servery současně zapsaly různé hodnoty pro stejný klíč, záznam s pozdějším TTL může být považován za prioritní. Amazon DynamoDB používá TTL pro automatické odstraňování zastaralých záznamů v tabulkách — to je vestavěná funkce, která nevyžaduje ruční správu.
Pro zvýšení výkonu po vypršení TTL se používají strategie čtení zastaralých dat. Stale-while-revalidate — okamžitě vrať zastaralá data klientovi a současně spusť aktualizaci na pozadí. Stale-if-error — vrať zastaralá data, pokud je zdroj dočasně nedostupný. Cache-Aside (Lazy Loading) — při neúspěchu cache načti data ze zdroje, ulož do cache s novým TTL a teprve potom vrať klientovi. Každá strategie se volí na základě požadavků na konzistenci dat.
V mobilních aplikacích je TTL klíčovým mechanismem správy cache. Podívejme se na hlavní scénáře, kde TTL určuje chování aplikace a uživatelský zážitek.
HTTP protokol poskytuje vestavěný mechanismus TTL prostřednictvím hlaviček Cache-Control. Direktiva max-age nastavuje TTL v sekundách: Cache-Control: public, max-age=3600 znamená, že odpověď může být cacheována po dobu 1 hodiny. Další direktivy s-maxage (pro sdílené cache, např. CDN) a stale-while-revalidate poskytují jemnější řízení. V případě shody TTL s hlavičkou expires má přednost max-age jako modernější standard HTTP/1.1.
| Typ dat | Doporučený TTL | Odůvodnění |
|---|---|---|
| Počasí | 10–30 minut | Předpovědi se neaktualizují častěji |
| Měnné kurzy | 15–60 sekund | Vysoká volatilita |
| Zpravodajský kanál | 2–5 minut | Rovnováha čerstvosti a výkonu |
| Uživatelský profil | 5–30 minut | Málokdy se mění v relaci |
| Seznam produktů | 10–60 minut | Ceny se nemění každou sekundu |
| Statické zdroje | 1–24 hodin | Verzovány prostřednictvím URL nebo ETag |
U obrázků může TTL dosáhnout několika dní, protože obsah se málokdy mění. Mobilní aplikace však často používají hybridní přístup: krátký TTL pro náhledy (30 minut — aktuálnost snímků) a dlouhý pro obrázky v plné velikosti (7 dní). Obrázky s HTTP hlavičkou Cache-Control: immutable by neměly být znovu vyžádány až do vypršení TTL — to je optimalizace pro statické zdroje navržená v RFC 8246. Takové obrázky jsou cacheovány na úrovni operačního systému (URLCache, OkHttp Cache) bez účasti aplikace.
V sítích se TTL nepoužívá pro cacheování, ale pro omezení životnosti paketů. Každý IP paket obsahuje pole TTL (8 bitů), které je snižováno o 1 každým směrovačem. Když TTL dosáhne 0, paket je zahozen a odesílateli je vrácena ICMP zpráva Time Exceeded. To zabraňuje nekonečnému směrování při smyčkách v síti.
DNS záznamy mají TTL, který určuje, jak dlouho může resolver (např. DNS cache ISP) ukládat záznam bez dotazu na autoritativní server. Typické hodnoty: 300 sekund (5 minut) pro záznamy s častými změnami, 86400 sekund (24 hodin) pro stabilní domény. CDN služby často nastavují nízký TTL (60–300 sekund) pro rychlé přesměrování provozu při výpadcích, zatímco statické domény mohou mít TTL až 7 dní. Při migraci serveru se doporučuje nejprve snížit TTL na 60 sekund (48 hodin před migrací), aby se změny rychle šířily.
V mobilních aplikacích se TTL používá pro správu relací a přístupových tokenů. JWT tokeny (JSON Web Tokens) obsahují pole exp (čas vypršení), který je absolutním Unixovým časem vypršení. Po vypršení se refresh token použije k získání nového přístupového tokenu bez opětovné autentizace. TTL přístupového tokenu je obvykle 1–24 hodin, refresh tokenu 7–30 dní. To je rovnováha mezi bezpečností (krátký TTL snižuje riziko úniku) a uživatelským zážitkem (dlouhý TTL snižuje četnost opětovných přihlášení).
Výběr TTL je inženýrské rozhodnutí závislé na typu dat, SLA aktuálnosti a nákladech na opětovný požadavek. Podívejme se na hlavní strategie.
Nejjednodušší přístup — všechny záznamy mají stejný TTL. Například cacheování všech API odpovědí na 5 minut. Výhoda: jednoduchost implementace a předvídatelné chování. Nevýhoda: nezohledňuje různou frekvenci změn různých typů dat. Fixní TTL je oprávněný pro homogenní data, kde všechny záznamy mají stejnou čerstvost — například kurz kryptoměn na jedné burze.
TTL se dynamicky mění v závislosti na chování dat. Například, pokud je záznam na serveru zřídka aktualizován, TTL se zvyšuje; pokud je aktualizován často — snižuje se. Implementace může využívat hlavičky HTTP odpovědí: hlavička Age (kolik sekund již odpověď strávila v cache) a hlavička Date umožňují výpočet zbývající životnosti. Adaptivní TTL poskytuje lepší hit-ratio, ale vyžaduje dodatečnou logiku na straně klienta.
Probabilistic Early Expiration (PEE) — technika, při které je TTL náhodně vybírán v daném rozsahu. Toto zabraňuje „efektu stáda“ (thundering herd), kdy mnoho požadavků současně vyprší a všichni klienti se současně obracejí ke zdroji. PEE je zvláště užitečná pro CDN a cache s vysokou zátěží: místo jednotného TTL 300 sekund se používá náhodná hodnota mezi 240 a 360 sekundami, což rovnoměrně rozděluje zátěž na zdroji.
Podívejme se na implementaci cache s TTL v Kotlinu pomocí absolutního vypršení. Každý záznam ukládá čas vytvoření a při čtení se kontroluje, zda TTL nevypršelo.
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) }
}
}
Třída Entry ukládá hodnotu a čas vytvoření + TTL (absolutní vypršení). Metoda get kontroluje vypršení při každém přístupu (lazy-cleanup) — prošlé záznamy jsou odstraněny pouze při pokusu o přístup k nim. Metodu cleanup lze periodicky volat z vlákna na pozadí pro dávkové odstranění všech zastaralých záznamů. ConcurrentHashMap zajišťuje bezpečnost vláken bez blokování celé cache.
V iOS je pro cacheování s TTL vhodné použít URLCache s nastavením memoryCapacity a diskCapacity. URLCache však nepodporuje individuální TTL pro různé požadavky. Podívejme se na vlastní obal NSCache s podporou TTL.
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
}
V této implementaci je NSCache použit jako bezpečný pro vlákna úložiště. CacheEntry obsahuje Data a expirationDate. Při get se kontroluje, zda čas nevypršel; pokud ano — záznam je odstraněn a je vráceno nil. TTL se nastavuje v sekundách prostřednictvím TimeInterval a může být pro každé URL jiný: typické hodnoty pro API odpovědi jsou 120 sekund pro dynamický obsah a 3600 pro statická data.
Často kladené otázky
Technicky jsou TTL a datum expirace totéž: časový interval, po kterém jsou data považována za neplatná. Rozdíl je v kontextu: termín TTL se používá v IT (cache, sítě, DNS), zatímco „datum expirace“ se častěji aplikuje v obchodní logice (promo kódy, předplatné). V implementaci jsou oba mechanismy identické — porovnání aktuálního času s časem vypršení.
Optimální TTL se volí empiricky. Metodika: začněte konzervativní hodnotou (30–60 sekund), postupně zvyšujte, dokud se neobjeví stížnosti na zastaralá data. Sledujte hit-ratio cache: pokud je pod 70 %, je TTL příliš krátký. Zohledněte SLA: pro finanční data může být TTL 1 sekunda, pro zprávy — 5 minut, pro profily — 30 minut.
Po vypršení max-age prohlížeč nebo mobilní aplikace považuje odpověď za stale (zastaralou). Při následujícím požadavku na stejné URL klient odešle požadavek s hlavičkou If-None-Match (ETag) nebo If-Modified-Since. Pokud se data nezměnila, server vrátí 304 Not Modified bez těla odpovědi a TTL se obnoví. Pokud se změnila — server vrátí 200 s novými daty a novým Cache-Control.
Technicky může být TTL velmi velký (max-age=31536000 — 1 rok), ale je to zřídka odůvodněné. Dokonce i statické zdroje se mohou změnit a klient se o tom nedozví až do vypršení TTL. Doporučuje se používat verzované URL (style.css?v=2) s dlouhým TTL: při změně souboru se URL změní a stará cache automaticky zastará.
TTL a strategie vytěsňování (LRU, FIFO) řeší různé úkoly. TTL určuje, kdy data zastarají — to je časové kritérium. LRU a FIFO určují, která data odstranit při přetečení cache — to je prostorové kritérium. Lze je kombinovat: záznam je odstraněn, pokud vypršel TTL NEBO je cache plná (podle LRU/FIFO). V produkčních systémech oba mechanismy pracují společně.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také