Choosing the Right Cache Eviction Policy
Your Redis node hits 95% memory utilization, the maxmemory limit triggers, and suddenly your application latency spikes from 15ms to 800ms…
Choosing the Right Cache Eviction Policy
Your Redis node hits 95% memory utilization, the maxmemory limit triggers, and suddenly your application latency spikes from 15ms to 800ms. The system metrics show green for uptime, but your database is melting under a sudden stampede of traffic.
This happens because you treated expiration and eviction as the same thing.

Expiration is driven by your business logic; you set a TTL because data becomes stale after ten minutes. Eviction is resource-driven infrastructure survival. When RAM fills up, the engine must drop keys to accept new ones, whether those keys have a TTL or not.
If your eviction policy doesn’t align with how your application actually queries data, the cache begins throwing out the wrong keys. This triggers a cascading failure: the cache ejects a high-value, frequently read key to make room for a low-value, single-use write. Your application immediately misses on the next read, hits the database, and forces the cache into a continuous loop of self-inflicted churn.
The Mental Model
To choose the right policy, you have to understand your working set dynamics. Your working set is the portion of your total data that your application actually uses frequently. The cache’s only job is to keep this working set in memory.
Predicting which data to keep is a guessing game based on past behavior. The cache assumes that if a key was used recently, or used many times, it will be used again soon.
But tracking this history isn’t free. Storing timestamps for recency or counters for frequency requires memory metadata and CPU cycles for every single read and write. If you want perfect eviction accuracy, you pay for it in throughput and memory overhead.

Choosing the Right Mechanism
Every standard policy has a blind spot that will eventually bite you in production.
A standard LRU policy breaks completely during automated cron jobs or large data exports. A single sequential scan across your database will write thousands of new, single-use keys into the cache, wiping out your actual hot working set in seconds.
LFU handles sequential scans better but suffers from historical decay failure. A key that was hit a million times during a Black Friday sale will stay in an LFU cache forever, blocking new, relevant data because its frequency counter is artificially inflated.
Modern production setups often use segmented or adaptive variants like ARC (Adaptive Replacement Cache) or W-TinyLFU. These mechanisms maintain two separate internal lists — one for recency and one for frequency — and dynamically shift the boundary between them based on real-time hit rates.

Implementation & Reality Checks
In a standard production environment like Redis, blindly relying on the default noeviction policy will crash your write path the moment memory fills up. Leaving it on volatile-lru is equally dangerous if your application writes keys without explicit TTLs, as those keys become un-evictable, unmovable blocks of leaked RAM.
Here is how you configure a Redis instance to act as a pure, smart data cache under heavy read/write workloads:
# redis.conf production tuning
# Hard limit on memory usage to prevent OS OOM killing
maxmemory 16gb
# All keys are eligible for LRU approximation, prioritizing memory reclaiming
maxmemory-policy allkeys-lru
# Raise the sample size to improve LRU accuracy closer to true LRU.
# Default is 5. Raising to 10 consumes slightly more CPU but prevents bad evictions.
maxmemory-samples 10
Approximated algorithms like the one in Redis save memory by sampling a random subset of keys and evicting the best candidate from that pool, rather than maintaining a massive, globally sorted linked list.
Hard Production Rules
- Match policy to access patterns, not defaults: Use
allkeys-lruif your traffic is driven by user activity waves. Useallkeys-lfuonly if your hot data is genuinely static and long-lived. - Isolate your instances: Do not mix a queue system (like Horizon) or a session store with a data cache on the same Redis instance. A full data cache will evict your user sessions or drop jobs.
- Watch the
evicted_keysmetric: A steadily climbing eviction count is normal. A sudden spike accompanied by a dropping hit-rate means your working set has outgrown your configuredmaxmemory. - Separate eviction from TTL compliance: If you need absolute certainty that a key lives for exactly one hour, handle it via application code or explicit TTLs. Never rely on an eviction policy to enforce business logic correctness.
메타데이터
- post_id
- b571d133eb78
- slug
- cache-eviction-policy-b571d133eb78
- url
- https://medium.com/@_suleyman/cache-eviction-policy-b571d133eb78
- canonical_url
- https://medium.com/@_suleyman/cache-eviction-policy-b571d133eb78
- author_url
- https://medium.com/@_suleyman
- status
- ok
- fetched_at
- 2026-06-20 20:29:01