Redis Running Out of Memory and Evicting Keys — How to Actually Fix It
Redis is hitting maxmemory and evicting keys you didn't expect to lose, or refusing writes entirely. Here's how to diagnose which eviction policy is wrong for your use case and fix it properly.
Redis hitting its memory ceiling shows up two ways: either it starts evicting keys silently (data just disappears, no error), or it starts refusing writes outright with OOM command not allowed. Both point to the same root cause, but the fix depends on which one you're seeing and why.
Step 1: Confirm What's Actually Happening
redis-cli INFO memoryused_memory_human:3.95G
maxmemory_human:4.00G
maxmemory_policy:noeviction
evicted_keys:0
If maxmemory_policy is noeviction and you're near the ceiling, Redis will start rejecting writes rather than silently dropping data — that's the OOM command not allowed error. If the policy is anything else (allkeys-lru, volatile-lru, etc.), check evicted_keys — a rapidly growing number means Redis is actively deleting data to stay under the limit, silently.
redis-cli INFO stats | grep evicted_keys
# Run twice, a minute apart — if the number is climbing, eviction is active right nowStep 2: Pick the Right Eviction Policy for Your Actual Use Case
This is where most misconfigurations live — Redis ships with noeviction as default, which is correct for some workloads and catastrophic for others.
noeviction → Refuses writes when full. Correct if Redis holds data you
CANNOT lose (primary data store, not just a cache).
allkeys-lru → Evicts least-recently-used keys, regardless of TTL.
Correct for pure caching where everything is disposable.
volatile-lru → Only evicts keys that have a TTL set, LRU order.
Correct if you mix cache data (with TTL) and
session/state data (no TTL) you can't afford to lose.
allkeys-lfu → Evicts least-frequently-used. Better than LRU for caches
with strong "hot key" patterns (some keys accessed
constantly, most rarely).
volatile-ttl → Evicts keys with the shortest remaining TTL first.
# Check current policy
redis-cli CONFIG GET maxmemory-policy
# Set the correct one for your use case — this takes effect immediately, no restart
redis-cli CONFIG SET maxmemory-policy allkeys-lruThe most common real-world mistake: using Redis as both a cache (disposable, fine to evict) and a session store (must not be evicted) in the same instance with allkeys-lru. This silently evicts active user sessions under memory pressure. Fix: either separate them into different Redis instances/databases, or use volatile-lru and make sure session keys have no TTL while cache keys do — but this conflates "no TTL = protected" with "permanent," which isn't guaranteed under volatile-lru either if you genuinely run out of room. The safest fix is separate instances.
# Run two logical Redis instances on separate ports — cheap insurance
# against this exact class of bug
# redis-cache.conf
port 6379
maxmemory 2gb
maxmemory-policy allkeys-lru
# redis-sessions.conf
port 6380
maxmemory 1gb
maxmemory-policy noevictionStep 3: Find What's Actually Consuming Memory
Sometimes the real fix isn't the eviction policy — it's that something is using far more memory than it should.
# Sample key sizes by pattern to find memory hogs
redis-cli --bigkeys
# Or for a more targeted look at memory by key pattern
redis-cli --memkeys --memkeys-samples 1000Biggest hash found 'user:session:bulk_cache' has 4,200,000 fields
Biggest string found 'analytics:daily:2026-06-17' has 89,400,320 bytes
A single oversized key (an analytics blob that should be in a proper datastore, not Redis) is a more common root cause than "we just need more memory" — check this before reaching for a bigger instance.
Step 4: If You Genuinely Need More Capacity
# Check current limit and actual server capacity
redis-cli CONFIG GET maxmemory
free -h# Raise the limit — but leave real headroom for Redis's own overhead
# (replication buffers, client output buffers, fragmentation)
redis-cli CONFIG SET maxmemory 6gb
# On a machine with 8GB RAM, this leaves the OS and Redis overhead 2GB —
# tight but workable. Don't set maxmemory close to total system RAM.# Make this permanent in redis.conf, not just runtime config
# (CONFIG SET doesn't survive a restart)
echo "maxmemory 6gb" >> /etc/redis/redis.conf
echo "maxmemory-policy allkeys-lru" >> /etc/redis/redis.confMonitoring So You Catch This Before It's a Production Incident
- alert: RedisMemoryNearLimit
expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.85
for: 10m
labels:
severity: warning
annotations:
summary: "Redis memory usage above 85% of maxmemory for 10m"
- alert: RedisEvictingKeysRapidly
expr: rate(redis_evicted_keys_total[5m]) > 100
for: 5m
labels:
severity: warning
annotations:
summary: "Redis is evicting more than 100 keys/sec — check if this is expected"The second alert matters even if eviction is your intended behavior — a sudden spike in eviction rate usually means something changed (a new feature writing way more keys, a TTL misconfiguration, a cache stampede) and is worth investigating even when "eviction is normal" for your setup.
Compare against alternatives if Redis memory limits are a recurring fight: Redis vs Dragonfly vs KeyDB
Today I Fixed
Short real fixes from production — posted daily
Stay ahead of the curve
Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.
Related Articles
Datadog Agent Not Sending Metrics — Diagnosis and Fix Guide
Datadog dashboards show no data, hosts appear offline, or custom metrics aren't showing up. Here's how to systematically diagnose and fix Datadog agent issues on Kubernetes and VMs.
Kafka Consumer Lag Keeps Growing — How to Diagnose and Fix It
Consumer lag climbing and you don't know why? Here's a step-by-step way to find whether it's slow processing, rebalancing storms, or partition skew — and how to actually fix each cause.
Prometheus Alerts Not Firing: Every Cause and Fix
Your Prometheus alert should have fired 30 minutes ago but nothing happened. Here's every reason alerts silently fail — routing, inhibition, receivers, and rule syntax.