Redis OOM Error (used memory > maxmemory): A Complete 5-Minute Emergency Fix Guide
You haven't even deployed, but suddenly production logs start getting plastered with this message:
(error) OOM command not allowed when used memory > 'maxmemory'.Reads still work, but every write command—SET, INCR, LPUSH, and the like—is rejected. If you use Redis as a session store or cache, this goes straight to a service outage. This post puts emergency treatment first and root-cause analysis second for anyone who is in an incident right now. Follow the roadmap below and you can restore writes in five minutes.
[1] Assess the situation with INFO memory (30 seconds)
[2] Raise maxmemory or change the eviction policy for immediate recovery (1 minute)
[3] Persist with CONFIG REWRITE (10 seconds)
[4] Prevent recurrence with TTLs and monitoring (afterward)1. Assess the Situation in 30 Seconds: How to Read INFO memory
First, you need to see what state Redis is in right now.
redis-cli INFO memory# Memory
used_memory:2147483648
used_memory_human:2.00G
used_memory_rss:2415919104
used_memory_rss_human:2.25G
maxmemory:2147483648
maxmemory_human:2.00G
maxmemory_policy:noeviction
mem_fragmentation_ratio:1.12
mem_allocator:jemalloc-5.3.0Look at just these four key metrics.
| Metric | Meaning | How to interpret |
|---|---|---|
used_memory | Memory Redis is using logically | Danger if close to or at maxmemory |
used_memory_rss | Physical memory (RSS) actually occupied by the OS | Fragmentation if much larger than used_memory |
mem_fragmentation_ratio | rss ÷ used_memory | 1.0–1.4 normal / ≥1.5 fragmentation / <1.0 swap suspected |
maxmemory_policy | Behavior when the limit is hit | noeviction is the direct cause of write rejections |
In the example above, used_memory == maxmemory and the policy is noeviction. In other words, this is the classic case: memory is full and there is no eviction policy, so writes are refused.
These helper commands are also worth knowing.
redis-cli MEMORY DOCTOR # Redis itself prints a diagnostic comment
redis-cli MEMORY STATS # detailed breakdown: peak.allocated, dataset.bytes, overhead.total, etc.
redis-cli --memkeys # sample the keys using the most memory (redis-cli 6.2+)
redis-cli MEMORY USAGE mykey # Bytes occupied by a specific key2. Immediate Recovery: Adjusting maxmemory and Choosing a Policy
You are in one of two situations: (A) you can give it more memory, or (B) it is a cache, so dropping some keys is acceptable.
(A) If you have spare RAM, just raise the limit
If the server has spare RAM, raise maxmemory with no downtime.
redis-cli CONFIG SET maxmemory 4gbThis command takes effect immediately, and writes start working again right after.
💡 Containers: In Docker/Kubernetes, if
maxmemoryis left at 0 (the default; unlimited on 64-bit), Redis never raises this OOM error and keeps using memory until it hits the container memory limit, at which point the kernel OOM-kills the container. The symptom is completely different, so in containers setmaxmemoryexplicitly and well below the limit (leave headroom for fork and buffers).
(B) If it is a pure cache, turn on an eviction policy
If you are using it as a cache but running with noeviction, that is the root problem. Switch to LRU so old keys are evicted automatically.
redis-cli CONFIG SET maxmemory-policy allkeys-lruThe moment you change the policy, the excess is evicted and writes recover immediately.
Comparison of maxmemory-policy options
Picking the policy that matches your situation is the key. Redis 8.6 added two LRM policies that only track writes, so the official docs now list 10 (Redis below 8.6 and Valkey have no LRM).
| Policy | Behavior | Target keys | For cache | For sessions / persistence |
|---|---|---|---|---|
noeviction | Reject writes (error) when the limit is hit | — | ✕ | ◎ (assuming you will scale memory) |
allkeys-lru | Evict the least recently used keys | All keys | ◎ | △ |
allkeys-lfu | Evict the least frequently used keys | All keys | ◎ | △ |
allkeys-lrm | Evict the least recently modified keys (Redis 8.6+) | All keys | ○ (read-heavy) | △ |
volatile-lru | LRU among keys that have a TTL | TTL keys only | ○ | ○ |
volatile-lfu | LFU among keys that have a TTL | TTL keys only | ○ | ○ |
volatile-lrm | LRM among keys that have a TTL (Redis 8.6+) | TTL keys only | ○ | ○ |
allkeys-random | Evict at random | All keys | △ | ✕ |
volatile-random | Random among TTL keys | TTL keys only | △ | △ |
volatile-ttl | Prefer keys closest to expiry | TTL keys only | ○ | ◎ (mixed TTL environment) |
Selection guide
- Pure cache:
allkeys-lru, orallkeys-lfuif access-frequency skew is large - Mix of TTL keys and persistent keys:
volatile-ttlorvolatile-lru(keys without a TTL are protected) - Data loss is absolutely not allowed (sessions, queues, persistent storage): keep
noevictionand scale memory. Do not try to ride it out with a policy change.
Persist the change
CONFIG SET is lost on restart. You must write it into the config file.
redis-cli CONFIG REWRITE⚠️
CONFIG REWRITEhas Redis rewriteredis.confitself. Hand-written comments or layout can change, so if you manage config with Ansible, Helm, or similar, it's safer to edit the source config and redeploy.
Or edit redis.conf directly.
maxmemory 2gb
maxmemory-policy allkeys-lru
maxmemory-samples 5maxmemory-samples is the sample size LRU/LFU uses when picking eviction candidates. The default of 5 is enough; you can raise it to 10 for more precision, but it uses more CPU.
3. Root-Cause Diagnosis: Five Scenarios That Trigger OOM
Once you have recovered, look at why it blew up. Organized as symptom → cause → how to confirm.
① Hit the maxmemory limit
- Symptom:
used_memory ≈ maxmemory, all writes rejected - Cause: Data growth exceeded allocated memory
- Confirm: Compare the two values in
INFO memory
② Policy is noeviction
- Symptom: It is a cache, but keys are never dropped—only errors
- Cause: The default
noevictionwas left in place for a cache - Confirm:
CONFIG GET maxmemory-policy
③ Server memory shortage due to fragmentation
- Symptom: no Redis OOM error, but the server swaps or the kernel OOM-kills Redis (the Redis OOM error is based on
used_memory, so fragmentation alone never triggers it) - Cause: Frequent key create/delete fragments the allocator; RSS balloons and pressures OS memory
- Confirm:
mem_fragmentation_ratioof 1.5 or higher
④ fork (COW) pressure from RDB/AOF rewrite
- Symptom: Memory spikes at
BGSAVE/AOF rewrite time; fork-failure logs - Cause: On fork, Copy-On-Write duplicates parent memory if there are many writes. Worst case, instantaneous usage can double
- Confirm: Log line
Can't save in background: fork: Cannot allocate memory;rdb_last_bgsave_statusinINFO persistence
⑤ Unbounded growth because keys have no TTL
- Symptom: used_memory increases monotonically over time
- Cause: It is a cache, but keys never expire and live forever
- Confirm:
redis-cli --bigkeys; watch theDBSIZEtrend
Check for keys without a TTL with SCAN, not KEYS *. KEYS walks every key in one go and blocks other commands.
redis-cli --scan --pattern 'cache:*' --count 1000 | head -n 100 # cursor-based iteration
redis-cli TTL cache:user:99 # -1 means no expiry, -2 means the key doesn't existField note: In production, the most commonly reported cause is #5—missing TTLs. A one-line code-review comment ("this SET is missing EX") would have prevented it, but it comes back as a 3 a.m. outage months later. Enforcing a TTL convention has a better cost-to-benefit ratio than policy tuning.
4. Recurrence-Prevention Checklist
Always put a TTL on cache keys. Set expiry at write time.
SET session:1234 "payload" EX 3600 # 1 hour
SETEX cache:user:99 600 "..." # 10 minutesHandle fragmentation. Turn on active defrag (Redis 4.0+). It only works when Redis is built with its bundled jemalloc, so first check that mem_allocator in INFO memory is jemalloc.
redis-cli CONFIG SET activedefrag yesIf fragmentation is severe and RSS will not come down, a restart as a last resort reclaims RSS (only after you have persisted the data).
Monitoring alerts. Use redis_exporter + Prometheus + Grafana and fire an alert at 80% memory usage.
groups:
- name: redis-memory
rules:
- alert: RedisMemoryHigh
expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Redis used_memory exceeded 80% of maxmemory"That single alert buys you time to scale or clean up before you hit the limit.
Capacity-sizing tip. Take production used_memory_rss, multiply by 1.3–1.5 for fork/COW headroom, and size maxmemory and server RAM from that. Be more conservative if you use RDB.
In Redis 7.x you can also cap client buffers with
maxmemory-clients. Per the official licenses page, Redis 7.2 and earlier are BSD-3, 7.4 moved to RSALv2/SSPLv1 (March 2024), and 8.0 added AGPLv3 as an option. Some teams moved to Valkey along the way; the eight maxmemory policies and commands in the Valkey docs match this guide (it has no LRM policies).
References: Official docs
The primary source for the behavior, settings, and errors covered in this post is the official documentation below. Check it for version-specific options and exact behavior.
FAQ
Q. If I change maxmemory-policy with CONFIG SET, are keys deleted immediately?
A. If you switch to an evicting policy and used_memory already exceeds maxmemory, keys are removed immediately until you are back under the limit. If you have persistent data without TTLs, use volatile-* instead of allkeys-*, or raise maxmemory first.
Q. I changed it with CONFIG SET, but it reverts after a restart.
A. CONFIG SET only changes the in-memory config. Run redis-cli CONFIG REWRITE to write it into redis.conf, or edit the config file yourself, so it survives a restart.
Q. used_memory still has headroom, but the server runs out of memory or gets OOM-killed. Why?
A. Redis's OOM command not allowed error only fires when used_memory exceeds maxmemory, so this is memory pressure outside Redis. Check mem_fragmentation_ratio. If it is 1.5 or higher, fragmentation has ballooned RSS and the OS is short on memory. Enable activedefrag yes, or persist and restart to reclaim RSS.
Sources · checked 2026-10-04
- Redis, Key eviction — 10 maxmemory policies; LRM policies since Redis 8.6
- Redis, Licenses — BSD-3 up to 7.2, RSALv2/SSPLv1 for 7.4, RSALv2/SSPLv1/AGPLv3 for 8.0+, changed March 2024
- Valkey, Key eviction — Valkey's eight maxmemory policies
Sources and checks vary by article. Only articles with a recorded check date, scope and sources below were checked, and only within that scope. For other articles, verify against the current docs for your version before applying anything, and email us about errors. Editorial policy · email us
This article has no recorded human check (date and scope) yet.
Comments
Be the first to comment.