Topic 2.2
maxmemory and Eviction Policies
In one line
When Redis reaches maxmemory, the eviction policy decides what happens: refuse writes (noeviction), or evict keys chosen by approximated LRU, LFU, TTL or randomness, from all keys or only those with a TTL. Choosing wrong either breaks writes or silently deletes important data.
Think of it like this
A small backpack on a long trip. When it's full you either stop picking things up (noeviction), throw out what you haven't used for longest (LRU), throw out what you use least often (LFU), or throw out whatever is going to expire soonest (volatile-ttl). Which rule is right depends on whether the backpack holds snacks or your passport.
Key ideas
- 01
maxmemorysets the limit (0 means no limit on 64-bit systems, so Redis grows until the OS kills it; always set it, typically 60–80% of the machine or container memory to leave room for fork copy-on-write, buffers and fragmentation). - 02
Policies (
maxmemory-policy):noeviction(default: writes that need memory fail withOOM command not allowed when used memory > 'maxmemory'; reads and deletes still work),allkeys-lru,allkeys-lfu,allkeys-random, and thevolatile-*versions (volatile-lru,volatile-lfu,volatile-random,volatile-ttl) that only consider keys with a TTL. If no volatile key exists,volatile-*policies behave likenoeviction. - 03
Redis's LRU is approximate: instead of a linked list over all keys, each key stores a 24-bit clock of last access. On eviction, Redis samples
maxmemory-sampleskeys (default 5) and feeds candidates into a pool of 16, evicting the best. Sampling 10 gets very close to true LRU at slightly more CPU. - 04
LFU (Redis 4+) stores an 8-bit logarithmic access counter (Morris counter) with decay:
lfu-log-factor(default 10) controls how many hits it takes to saturate, andlfu-decay-time(default 1 minute) halves counters of keys not accessed. LFU resists cache pollution from one-time scans that would flush an LRU cache. - 05
Eviction happens on the write path: before executing a command that may need memory, Redis evicts until it's under the limit. Big writes into a full instance can trigger long eviction loops ("eviction storms") and latency spikes.
maxmemory-eviction-tenacitycontrols how much time each round may spend. - 06
Replicas ignore
maxmemoryby default (replica-ignore-maxmemory yes); they delete keys when the primary's evictions arrive as DELs. Keep the replica's memory at least as large as the primary's. - 07
Rule of thumb: pure cache →
allkeys-lru(orallkeys-lfufor skewed popularity). Stateful data (queues, locks, sessions you can't lose) →noevictionon a separate instance, with alerts well before the limit. Mixing cache and critical data in one instance withvolatile-lruworks only if every cache key has a TTL and no critical key does, which is fragile.
Code & diagrams
127.0.0.1:6379> CONFIG SET maxmemory 100mb
OK
127.0.0.1:6379> CONFIG SET maxmemory-policy noeviction
OK
# ... fill memory ...
127.0.0.1:6379> SET k "v"
(error) OOM command not allowed when used memory > 'maxmemory'.
127.0.0.1:6379> GET existing-key # reads still work
"..."
127.0.0.1:6379> CONFIG SET maxmemory-policy allkeys-lfu
OK
127.0.0.1:6379> SET k "v"
OK
127.0.0.1:6379> OBJECT FREQ hot:key # LFU counter (needs an LFU policy)
(integer) 21
127.0.0.1:6379> INFO stats
evicted_keys:40211
keyspace_hits:9121212
keyspace_misses:311002Interview problem
The problem
Cache full: explain every policy
Redis reaches maxmemory. Explain what happens under each policy. Which would you choose for a pure cache? What changes if the same Redis also holds critical data such as locks, rate-limit counters and job queues?
The interviewer follows up
Why is Redis's LRU approximate, and does it matter?
What's an eviction storm and how do you avoid it?
When it breaks
maxmemory not set on a cache in a container with a 4 GB limit
What you see
Redis grows past 4 GB, the kernel OOM-kills it, and the cache (plus anything else stored there) is gone; with persistence on, it may crash-loop while reloading.
Fix & prevent
Set maxmemory to ~70–80% of the container limit and an explicit policy; monitor used_memory and RSS.
Distributed locks stored in a cache instance with allkeys-lru
What you see
Under memory pressure a lock key is evicted; a second worker acquires the lock while the first still works, and a job runs twice.
Fix & prevent
Put coordination data on a noeviction instance; use fencing tokens for correctness (Topic 12.2).
Explain it without notes
Explain the difference between allkeys-lru and volatile-lru, and when volatile-lru acts like noeviction.
Why can LFU be better than LRU for a cache?
Practice
In the lab, set maxmemory 20mb and allkeys-lru, load 100K keys, then read a subset repeatedly while loading more. Check which keys survive.
Compute hit ratio = keyspace_hits / (keyspace_hits + keyspace_misses) from INFO stats on your lab instance.
Trade-offs
- ↔
noevictionprotects data but turns memory pressure into write errors;allkeys-*keeps writes working but silently loses data. - ↔
Larger
maxmemory-samplesmakes eviction more accurate for a little more CPU per eviction.
Done when you can
I can explain all eight policies and what happens at the limit under each.
I can choose a policy for pure cache and explain why critical data needs a separate instance.
I know how approximate LRU and LFU work.