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 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.
(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 the 8 maxmemory-policy options
Picking the policy that matches your situation is the key.
| 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 | ◎ (increasingly recommended) | △ |
volatile-lru | LRU among keys that have a TTL | TTL keys only | ○ | ○ |
volatile-lfu | LFU among keys that have a TTL | 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 REWRITEOr 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
③ Effective shortage due to memory fragmentation
- Symptom: used_memory still has headroom, but you get OOM or OS swap
- Cause: Frequent key create/delete fragments jemalloc; 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
Field 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+).
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, and adoption of frequency-basedallkeys-lfuis growing. As a side note, after the 2024–2025 license change (RSAL → AGPL) some teams are moving to Valkey, but maxmemory behavior and commands are the same, so this guide applies as-is.
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 I still get OOM. Why?
A. 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.
Nodelog는 모든 콘텐츠의 내용과 출처를 공개 전에 검토합니다. 환경(OS·버전)에 따라 결과가 달라질 수 있는 기술 정보는 공식 문서와 함께 확인하며, 검토 기준과 정정 원칙은 편집 정책에서 안내합니다. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.
Comments
Be the first to comment.