PATTERN Cited by 1 source
Age-based exponential TTL¶
Pattern¶
When caching time-series data where recent buckets are unsettled and old buckets are final, assign each bucket a TTL that scales monotonically with the bucket's data age:
- Young buckets get short TTLs (cycle fast → pick up late-arriving corrections).
- Old buckets get long TTLs (cache them aggressively → carry the hit-rate).
- Cap the TTL at an operational maximum (prevents indefinite stale-cache states across schema / data-model changes).
The "exponential" shape is the canonical Netflix form — TTL doubles per additional minute of data age — but any monotonically- increasing schedule (linear, piecewise, logarithmic) qualifies as long as it tracks the confidence-grows-with-age property.
Canonical schedule (Netflix)¶
Netflix's Druid cache (Source: sources/2026-04-06-netflix-stop-answering-the-same-question-twice-interval-aware-caching-for-druid):
| Bucket age | TTL |
|---|---|
| < 2 min | 5 s (floor) |
| 2 min | 10 s |
| 3 min | 20 s |
| 4 min | 40 s |
| 5 min | 80 s |
| ≥ 60 min | 1 hour (ceiling) |
Doubling behaviour means the TTL ceiling is reached after ~10 minutes of data age; anything older than that uses the 1-hour cap.
When to use¶
- Data arrives with out-of-order / delayed events → recent values are not yet final.
- Rolling-window queries read a wide range where only the newest slice is volatile.
- Consumer tolerates bounded staleness (see staleness-vs-load trade-off).
- Storage layer supports per-entry TTLs (e.g. Cassandra /
KVDAL per-inner-key TTLs, Redis
EXPIRE-per-key).
When not to use¶
- Data is point-in-time consistent and never changes after write (use a long uniform TTL or content-addressed storage).
- Data is constantly mutated (no "age monotonic confidence" property) — use invalidation- based instead.
- Storage layer only supports a single TTL per object — the pattern degrades to uniform TTL.
Why it's a sub-pattern of patterns/interval-aware-query-cache¶
Interval-aware caching + age-based exponential TTL are orthogonal but complementary:
- Interval-aware (bucketing) solves shift-invariance — cache hits survive window-boundary changes.
- Age-based exponential TTL solves late-arrival handling — fresh buckets refresh fast, old buckets linger.
Together they resolve the uniform-TTL staleness dilemma — fresh data gets short TTL and settled data gets long TTL, inside one cache, with no manual eviction.
Why "exponential" specifically¶
- The confidence-of-settlement curve for most event pipelines is approximately exponential in age (late arrivals are Pareto- distributed in delay).
- Doubling reaches the ceiling in a small number of steps, which bounds the TTL-table size.
- Doubling is trivial to encode without a lookup table
(
min(max_ttl, base * 2^(age_minutes - 1))).
But the pattern isn't about the specific exponential shape — it's about the monotonic-with-age property. A team could use linear growth, piecewise, or logarithmic, with the same architectural benefit.
Seen in¶
- sources/2026-04-06-netflix-stop-answering-the-same-question-twice-interval-aware-caching-for-druid — canonical wiki instance.
Related¶
- concepts/exponential-ttl — the concept page.
- concepts/late-arriving-data — the forcing function.
- concepts/staleness-vs-load-tradeoff — the meta-trade-off.
- concepts/granularity-aligned-bucket — the units this TTL is applied to.
- concepts/cache-ttl-staleness-dilemma — the uniform-TTL problem this resolves.
- systems/netflix-druid-interval-cache
- patterns/interval-aware-query-cache — the parent pattern.