When Redis’s memory usage hits the maxmemory limit, something has to go. The eviction policy decides what. There are eight options — most boil down to “evict by recency, by frequency, by TTL, or randomly”.
In simple language — think of it like a small fridge. When it’s full and you want to put in a new item, you have to throw something out. Do you toss the oldest? The least-eaten? Or just grab whatever’s in front?
Setting it up
CONFIG SET maxmemory 2gb
CONFIG SET maxmemory-policy allkeys-lru
Or in redis.conf:
maxmemory 2gb
maxmemory-policy allkeys-lru
If you don’t set maxmemory, Redis will grow until the OS kills it (OOM). Always set it in production.
The eight policies
Refuse new writes with OOM error. Reads still work.
Evict from any key in the dataset.
Only evict from keys that have a TTL set.
The full list:
| Policy | What it evicts |
|---|---|
noeviction | Nothing — new writes fail when full |
allkeys-lru | Least Recently Used, any key |
allkeys-lfu | Least Frequently Used, any key |
allkeys-random | A random key |
volatile-lru | LRU, but only keys with TTL |
volatile-lfu | LFU, but only keys with TTL |
volatile-random | Random key with TTL |
volatile-ttl | The key closest to expiring |
LRU vs LFU — what’s the difference?
LRU (Least Recently Used) — kicks out the key that hasn’t been touched in the longest time. Good when “recent = important”. A user who hit the site 1 minute ago probably matters more than one who hit it yesterday.
LFU (Least Frequently Used) — kicks out the key that’s been touched the fewest times overall. Good when popularity matters more than recency. A homepage hit 10000 times shouldn’t get evicted just because nothing touched it in the last 5 seconds.
Access log: A A A A A A B C D E
(A hit 6 times, then B C D E one each)
LRU evicts: A ← A is oldest, even though it’s hottest
LFU evicts: B ← B has been touched only once
LRU is an approximation in Redis — it samples a few keys and evicts the least recent. Same for LFU. Not exact, but cheap and good enough. Tune via maxmemory-samples (default 5, higher = more accurate, more CPU).
When to use which
Pure cache, no TTLs, hot-cold access:
→ allkeys-lru (default-ish good choice)
Pure cache, popularity-driven (e.g. trending content):
→ allkeys-lfu
Mixed dataset: some keys are "real data", some are cached with TTLs:
→ volatile-lru or volatile-lfu
(protects the no-TTL keys, only evicts the explicitly-cached ones)
Redis as a job queue or session store you can't afford to lose:
→ noeviction
(let it OOM and alert you — better than silent data loss)
Don't care, just keep it running:
→ allkeys-random (rarely the right choice, but cheapest)
Inspecting evictions
INFO stats | grep evicted
# evicted_keys:12047
# evicted_clients:0
INFO memory | grep maxmemory
# maxmemory:2147483648
# maxmemory_policy:allkeys-lru
If evicted_keys is climbing fast, your cache is too small for the working set — either bump maxmemory or shrink your data (better compression, shorter TTLs, drop hot-but-useless fields).
A subtle thing — noeviction is the default. If you set maxmemory but forget the policy, writes will start failing once you hit the limit. Always set both explicitly.