Expiration & TTL
TTL (time-to-live) is non-negotiable for cache keys — without EX/PX every SET lives forever until manual DELETE or OOM.
Introduction
TTL (time-to-live) is non-negotiable for cache keys — without EX/PX every SET lives forever until manual DELETE or OOM. Redis expires keys passively on access and actively via sampling (~10 keys/second per DB plus faster cycle when memory pressure hits).
Mass simultaneous expiry causes cache stampede — thousands of requests hit DB when hot keys expire together. Jitter TTL and single-flight refresh prevent avalanches.
volatile-* eviction policies only remove keys with TTL set — understand the difference from allkeys-*.
Understanding the topic
Key concepts
- EX seconds / PX milliseconds on SET — set with expiry.
- EXPIRE key seconds — add TTL to existing key.
- TTL key — remaining seconds; -1 no expiry; -2 missing.
- PERSIST — remove TTL.
- Passive expire on read; active random sampling.
- volatile-lru evicts expirable keys when maxmemory hit.
flowchart LRSET -->|EX| KeyTTLAccess -->|passive| DeleteSample -->|active| Evict
Step-by-step explanation
- Expiry stored in key metadata dict.
- On access, Redis checks expiry and deletes if past.
- Active cycle samples random keys with TTL.
- Expired keys deleted or evicted per policy.
- EXPIREAT/PEXPIREAT use absolute Unix timestamps.
Syntax reference
Common commands
- Always EX on cache writes.
- TTL -2 means key gone — treat as cache miss.
- Add random jitter in app: baseTtl + random(0, 60).
SET session:abc data EX 3600TTL session:abcEXPIRE cache:product:1 1800SET cache:flag 1 EX 300 NX
Informative example
Cache write with jittered TTL to reduce stampede:
# Shell illustrates jitter conceptBASE=3600JITTER=$(( RANDOM % 300 ))redis-cli SET "product:42" "$JSON" EX $((BASE + JITTER))
In Java: Duration.ofSeconds(3600 + ThreadLocalRandom.current().nextInt(300)). Spring @Cacheable supports custom TTL per cache name.
Real-world use
Real-world use cases
- Session timeout — EXPIRE aligned with JWT.
- API cache — 5–60 min TTL by volatility.
- Rate limit windows — EXPIRE on counter key.
- OTP codes — EX 300 one-time.
- Distributed lock — SET NX EX auto-release.
Best practices
- TTL on every cache key — no exceptions.
- Jitter TTL on hot keys.
- Refresh TTL on session activity (sliding window).
- Monitor expired_keys_per_sec in INFO stats.
- Use volatile-lru when most keys have TTL.
- Plan stampede protection (sync=true, mutex).
Common mistakes
- Forever keys — memory leak.
- Identical TTL on millions of keys — thundering herd.
- Assuming EXPIRE extends on read without EXPIRE call.
- volatile-lru with keys missing TTL — they never evict.
Advanced interview questions
Q1BeginnerTTL return values?
Q2BeginnerPassive vs active expiry?
Q3IntermediateWhat is cache stampede?
Q4IntermediatePrevent stampede?
Q5Advancedvolatile-lru vs allkeys-lru?
Summary
TTL prevents unbounded memory growth.