Why Redis Doesn’t Immediately Free Expired Keys – Understanding Its Deletion Strategies
Redis does not instantly release memory for expired keys; instead it employs three deletion strategies—timed, periodic, and lazy—to balance memory usage, CPU load, and data accuracy, with periodic scans optimized by random sampling and time limits.
Expiration Deletion in Redis
When a key reaches its TTL (time‑to‑live) it becomes logically expired: the key is no longer returned to clients, but the memory occupied by the key is not always freed instantly. Redis uses a hybrid strategy that combines periodic scanning with lazy deletion to balance memory reclamation, CPU usage, and data correctness.
1. Timed Deletion
When a key is set with an expiration, Redis can create a timer that fires exactly at the expiration moment and deletes the key immediately. This approach releases memory promptly but, if many keys expire at the same time, the timer callbacks generate a large CPU spike that degrades response time and throughput. Because of this cost, Redis does not rely on timed deletion for the general case.
2. Periodic Deletion (Active Expiration)
Redis stores every key that has an associated expiration in a dedicated dictionary (the expires dictionary ). A background scanner runs by default 10 times per second . Each scan performs the following steps:
Randomly select 20 keys from the expires dictionary.
Check the expireAt timestamp of each selected key.
If more than 25 % of the sampled keys are already expired, repeat the sampling immediately (a second pass).
The total CPU time spent on a scan is limited to 25 ms to avoid interfering with client request processing.
Expired keys found during the scan are deleted, freeing their memory. Because the scan samples only a small subset of keys, it avoids the heavy CPU load of scanning the entire dictionary.
3. Lazy Deletion (Passive Expiration)
Whenever a client accesses a key (e.g., GET, HGET, etc.), Redis checks the key’s expiration timestamp. If the key is already past its TTL, Redis deletes it on the spot before returning a result. This guarantees that no expired data is ever returned to the client.
Combined Strategy
Redis enables both periodic scanning and lazy deletion simultaneously. Periodic scans proactively clean up a portion of expired keys, reducing the amount of stale data that could be accessed. Lazy deletion serves as a safety net, ensuring that any remaining expired keys are removed the moment they are accessed.
The combination provides a practical trade‑off:
Memory consumption : Expired keys are eventually reclaimed, preventing unbounded memory growth.
CPU overhead : The limited‑size random sampling and time cap keep CPU usage predictable.
Data correctness : Clients never see expired values because lazy deletion guarantees immediate removal on access.
Senior Tony
Former senior tech manager at Meituan, ex‑tech director at New Oriental, with experience at JD.com and Qunar; specializes in Java interview coaching and regularly shares hardcore technical content. Runs a video channel of the same name.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
