TTL (Time To Live) — параметар који одређује максимално време у којем се подаци сматрају ажурним. Након истека TTL, запис се означава као застарео (stale) и мора бити обрисан или ажуриран. Према Mozilla Developer Network (2026), механизам TTL је основа HTTP кеширања кроз заглавље Cache-Control: max-age и користи се у свим савременим претраживачима и мобилним апликацијама за оптимизацију мрежних захтева.
Главно
TTL (Time To Live) — је временска ознака или интервал након којег се подаци сматрају неважећим. У контексту кеширања, TTL одређује колико дуго запис може да се чува у кешу пре него што ће морати да се поново затражи из изворног извора. У мрежним протоколима, TTL ограничава животни век пакета, спречавајући бесконачно усмеравање.
Вредност TTL се увек изражава у јединицама времена: милисекундама, секундама, минутима или сатима. Након истека постављеног времена, запис се или брише из кеша, или означава као stale (застарео). При следећем захтеву ка застарелом запису, систем може да врати застареле податке са каснијим ажурирањем (stale-while-revalidate) или да блокира захтев до добијања свежих података.
Избор TTL је увек компромис између ажурности података и перформанси. Прекратак TTL (1–5 секунди) приморава апликацију да често извршава мрежне захтеве, поништавајући предности кеширања. Предуг TTL (сати/дани) повећава риск приказивања кориснику застарелих информација. Оптимална вредност зависи од типа података: курсеви валута — секунде, време — минути, верзија АПИ — сати.
TTL је пасивна инвалидација: подаци се аутоматски бришу након истека времена. Алтернатива је активна инвалидација, када извор података обавештава кеш о променама (нпр. путем WebSocket порука или push обавештења). Пасивна инвалидација кроз TTL је једноставнија за имплементацију, али не гарантује тренутну ажурност. Активна инвалидација је сложенија, али омогућава одржавање података у ажурном стању без кашњења карактеристичних за TTL.
Механизам TTL се може имплементирати на два начина: апсолутно истецање (absolute expiration) и релативно истецање (relative expiration). Код апсолутног истецања, запис чува одређено време када ће постати неважећи. Код релативног — бележи се време креирања записа и TTL као интервал, а провера се врши израчунавањем creationTime + TTL > currentTime.
При сваком захтеву ка кешу, систем проверава TTL сваког записа. Ако је TTL истекао, подаци се бришу или означавају као stale, а захтев се усмерава ка извору. За оптимизацију провере TTL може да се користи scheduled-cleanup (периодично брисање свих истеклих записа) или lazy-cleanup (брисање само при приступу запису). Lazy-cleanup је ефикаснији у погледу меморије, јер не захтева позадинску нит за скенирање целог кеша.
У дистрибуираним системима, TTL се такође користи за аутоматско решавање сукоба. На пример, ако су два сервера истовремено записала различите вредности за исти кључ, запис са каснијим TTL може бити приоритетан. Amazon DynamoDB користи TTL за аутоматско брисање застарелих записа у табелама — то је уграђена функција која не захтева ручно управљање.
За повећање перформанси након истека TTL, примењују се стратегије читања застарелих података. Stale-while-revalidate — одмах врати застареле податке клијенту и истовремено покрени ажурирање у позадини. Stale-if-error — врати застареле податке ако је извор привремено недоступан. Cache-Aside (Lazy Loading) — при промашају кеша, учитај податке из извора, сачувај у кешу са новим TTL и тек онда врати клијенту. Свака стратегија се бира на основу захтева за конзистентношћу података.
У мобилним апликацијама, TTL је кључни механизам управљања кешом. Размотримо главне сценарије у којима TTL одређује понашање апликације и корисничко искуство.
HTTP протокол пружа уграђени TTL механизам кроз заглавља Cache-Control. Директива max-age поставља TTL у секундама: Cache-Control: public, max-age=3600 значи да се одговор може кеширати 1 сат. Додатне директиве s-maxage (за дељене кешеве, нпр. ЦДН) и stale-while-revalidate омогућавају финије управљање. У случају поклапања TTL са expires заглављем, приоритет има max-age као савременији HTTP/1.1 стандард.
| Тип података | Препоручени TTL | Образложење |
|---|---|---|
| Време | 10–30 минута | Прогнозе се не ажурирају чешће |
| Курсеви валута | 15–60 секунди | Висока волатилност |
| Новости фед | 2–5 минута | Баланс свежине и перформанси |
| Профил корисника | 5–30 минута | Ретко се мења у сесији |
| Листа производа | 10–60 минута | Цене се не мењају сваке секунде |
| Статички ресурси | 1–24 сата | Верзионишу се кроз URL или ETag |
За слике, TTL може да достигне неколико дана, јер се садржај ретко мења. Међутим, мобилне апликације често користе хибридни приступ: кратак TTL за прегледе (30 минута — ажурност оквира) и дуг за слике у пуној величини (7 дана). Слике са HTTP заглављем Cache-Control: immutable уопште не треба да се поново захтевају до истека TTL — то је оптимизација за статичке ресурсе предложена у RFC 8246. Такве слике се кеширају на нивоу оперативног система (URLCache, OkHttp Cache) без учешћа апликације.
У мрежама, TTL се користи не за кеширање, већ за ограничавање животног века пакета. Сваки IP пакет садржи TTL поље (8 бита) које се смањује за 1 на сваком рутеру. Када TTL достигне 0, пакет се одбацује, а пошиљаоцу се враћа ICMP порука Time Exceeded. Ово спречава бесконачно усмеравање при петљама у мрежи.
DNS записи имају TTL који одређује колико дуго резолвер (нпр. DNS кеш ИСП-а) може да чува запис без упита ауторитетном серверу. Типичне вредности: 300 секунди (5 минута) за записе са честим променама, 86400 секунди (24 сата) за стабилне домене. ЦДН услуге често постављају низак TTL (60–300 секунди) за брзо преусмеравање саобраћаја у случају кварова, док статички домени могу имати TTL до 7 дана. При миграцији сервера, препоручује се прво смањити TTL на 60 секунди (48 сати пре миграције), како би се промене брзо прошириле.
У мобилним апликацијама, TTL се користи за управљање сесијама и токенима приступа. JWT токени (JSON Web Tokens) садрже exp поље (време истека) које је апсолутно Unix време истека. Након истека, рефреш токен се користи за добијање новог токена за приступ без поновне аутентификације. TTL токена за приступ обично износи 1–24 сата, а рефреш токена — 7–30 дана. То је баланс између сигурности (кратак TTL смањује ризик цурења) и корисничког искуства (дуг TTL смањује учесталост поновних пријава).
Избор TTL је инжењерска одлука која зависи од типа података, SLA по ажурности и цене поновног захтева. Размотримо главне стратегије.
Најједноставнији приступ — сви записи имају исти TTL. На пример, кеширање свих АПИ одговора 5 минута. Предност: једноставност имплементације и предвидљиво понашање. Недостатак: не узима у обзир различиту учесталост промене различитих типова података. Фиксни TTL је оправдан за хомогене податке, где сви записи имају исту свежину — на пример, курс криптовалута на једној берзи.
TTL се динамички мења у зависности од понашања података. На пример, ако се запис ретко ажурира на серверу, TTL се повећава; ако се често ажурира — смањује. Имплементација може да користи заглавља HTTP одговора: заглавље Age (колико секунди је одговор већ провео у кешу) и заглавље Date омогућавају израчунавање преосталог времена живота. Адаптивни TTL даје бољи hit-ratio, али захтева додатну логику на клијенту.
Probabilistic Early Expiration (PEE) — техника којом се TTL бира случајно у одређеном опсегу. Ово спречава ефекат стада (thundering herd), када много захтева истовремено истекну и сви клијенти истовремено се обрате извору. PEE је посебно корисна за CDN и кешеве са високим оптерећењем: уместо јединственог TTL од 300 секунди, користи се случајна вредност од 240 до 360 секунди, што равномерно расподељује оптерећење на извору.
Размотримо имплементацију кеша са TTL у Котлину коришћењем апсолутног истецања. Сваки запис чува време креирања, и при читању проверава се да ли је TTL истекао.
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 проверава истецање при сваком приступу (lazy-cleanup) — истекли записи се бришу само при покушају приступа њима. Метода cleanup може да се позива периодично из позадинске нити за групно брисање свих застарелих записа. ConcurrentHashMap обезбеђује сигурност нити без блокирања целог кеша.
У iOS-у за кеширање са TTL погодно је користити URLCache са подешавањем memoryCapacity и diskCapacity. Међутим, URLCache не подржава индивидуални TTL за различите захтеве. Размотримо прилагођени омотач NSCache са подршком 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
}
У овој имплементацији, NSCache се користи као сигуран за нити склад. CacheEntry садржи Data и expirationDate. При get проверава се да ли је време истекло; ако јесте — запис се брише и враћа се nil. TTL се поставља у секундама кроз TimeInterval и може бити различит за сваки URL: типичне вредности за АПИ одговоре су 120 секунди за динамички садржај и 3600 за статичке податке.
Често постављана питања
Технички, TTL и рок трајања су исто: временски интервал након којег се подаци сматрају неважећим. Разлика је у контексту: термин TTL се користи у IT (кешеви, мреже, DNS), а рок трајања чешће у пословној логици (промо кодови, претплате). У имплементацији, оба механизма су идентична — поређење тренутног времена са временом истека.
Оптималан TTL се бира емпиријски. Метода: почните са конзервативном вредношћу (30–60 секунди), постепено повећавајте док се не појаве жалбе на застареле податке. Пратите hit-ratio кеша: ако је испод 70%, TTL је превише кратак. Узмите у обзир SLA: за финансијске податке TTL може бити 1 секунда, за вести — 5 минута, за профиле — 30 минута.
Након истека max-age, претраживач или мобилна апликација сматра одговор stale (застарелим). При следећем захтеву ка истом URL, клијент шаље захтев са заглављем If-None-Match (ETag) или If-Modified-Since. Ако се подаци нису променили, сервер враћа 304 Not Modified без тела одговора и TTL се обнавља. Ако су се променили — сервер враћа 200 са новим подацима и новим Cache-Control.
Технички TTL може бити веома велик (max-age=31536000 — 1 година), али то је ретко оправдано. Чак и статички ресурси се могу променити, а клијент неће знати за то до истека TTL. Препоручује се коришћење верзионисаних URL-ова (style.css?v=2) са дугим TTL: при промени датотеке, URL се мења, а стари кеш аутоматски застарева.
TTL и стратегије потискивања (LRU, FIFO) решавају различите задатке. TTL одређује када подаци постају неажурни — то је временски критеријум. LRU и FIFO одређују које податке уклонити при препуњавању кеша — то је просторни критеријум. Они се могу комбиновати: запис се брише ако је TTL истекао ИЛИ је кеш препун (према LRU/FIFO). У производним системима, оба механизма раде заједно.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође