Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Redis By James Joyner IV · · 10 min read

Redis Error Guide: 'OOM command not allowed when used memory > maxmemory' — Free Memory or Fix the Eviction Policy

Fix OOM command not allowed when used memory > maxmemory in Redis: diagnose maxmemory limits, noeviction policy, big keys, fragmentation, and unbounded data growth.

  • #redis
  • #troubleshooting
  • #errors
  • #memory

Overview

Redis returns OOM command not allowed when used_memory has reached the configured maxmemory limit and the current maxmemory-policy will not evict anything to make room. With the default noeviction policy, once the limit is hit every write-type command (SET, LPUSH, HSET, SADD, INCR) is rejected while reads and deletes still work.

The literal error clients receive:

(error) OOM command not allowed when used memory > 'maxmemory'.

This is not a bug — it is the memory ceiling doing exactly what it was told. The question is always: is maxmemory set correctly, is the eviction policy appropriate for this workload (cache vs. datastore), and why did the dataset grow to the limit? Blindly raising maxmemory just moves the wall.

Symptoms

  • Writes fail with OOM command not allowed; GET/DEL/EXPIRE still work.
  • INFO memory shows used_memory at or above maxmemory.
  • evicted_keys is 0 (with noeviction) even though the instance is full.
redis-cli SET session:42 payload
(error) OOM command not allowed when used memory > 'maxmemory'.
redis-cli INFO memory | grep -E 'used_memory_human|maxmemory_human|maxmemory_policy|mem_fragmentation_ratio'
used_memory_human:4.00G
maxmemory_human:4.00G
maxmemory_policy:noeviction
mem_fragmentation_ratio:1.12

Common Root Causes

1. maxmemory reached with noeviction

The instance is used as a cache but left on noeviction, so it never frees keys and hits the wall.

redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy
1) "maxmemory"
2) "4294967296"
1) "maxmemory-policy"
2) "noeviction"

2. Keys without TTLs (unbounded growth)

The app writes keys that never expire, so the dataset only grows.

redis-cli INFO keyspace
redis-cli DBSIZE
# Keyspace
db0:keys=8500000,expires=12,avg_ttl=0

expires far smaller than keys means almost nothing is set to expire.

3. A few huge keys dominate memory

One giant list, hash, or set (a “big key”) consumes most of the memory.

redis-cli --bigkeys
redis-cli MEMORY USAGE some:big:key
Biggest list found 'events:stream' has 9128341 items

4. High fragmentation

used_memory is far below used_memory_rss; the allocator is holding memory the dataset no longer uses.

redis-cli INFO memory | grep -E 'used_memory_rss_human|mem_fragmentation_ratio|allocator_frag_ratio'
mem_fragmentation_ratio:1.68

A ratio well above 1.5 signals fragmentation worth addressing.

Diagnostic Workflow

Step 1: Confirm the limit and policy

redis-cli INFO memory | grep -E 'used_memory_human|maxmemory_human|maxmemory_policy'
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy

If used_memorymaxmemory and the policy is noeviction, that is the OOM.

Step 2: Ask MEMORY DOCTOR

redis-cli MEMORY DOCTOR
redis-cli MEMORY STATS | grep -E 'peak.allocated|dataset.bytes|keys.count'

Step 3: Find where the memory went

redis-cli --bigkeys
redis-cli INFO keyspace
# Sample specific suspects
redis-cli MEMORY USAGE events:stream

Step 4: Check fragmentation and eviction stats

redis-cli INFO memory | grep -E 'used_memory_rss_human|mem_fragmentation_ratio'
redis-cli INFO stats | grep -E 'evicted_keys|expired_keys|keyspace_misses'

Step 5: Check the log for OOM context

sudo journalctl -u redis-server --no-pager | grep -iE 'OOM|maxmemory|used_memory' | tail

Example Root Cause Analysis

At 14:30 the API starts throwing OOM command not allowed on every session write. INFO memory shows used_memory_human:4.00G against a 4G maxmemory with maxmemory_policy:noeviction. Reads still work, so this is purely the write ceiling.

redis-cli --bigkeys and INFO keyspace reveal the cause: an event pipeline was pushing to a single list events:stream with no trimming and no TTL, and it had grown to over 9 million entries, consuming most of the instance:

Biggest list found 'events:stream' has 9128341 items
db0:keys=8500012,expires=9,avg_ttl=0

This instance is genuinely a cache, so the correct fix is two-fold — cap the runaway key and set an eviction policy so a single hot key can never wedge the whole instance again:

# Immediate relief: trim the runaway list
redis-cli LTRIM events:stream -100000 -1

# Make it a proper cache: evict least-recently-used keys under pressure
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG REWRITE          # persist to redis.conf

redis-cli INFO memory | grep used_memory_human   # drops below maxmemory
redis-cli SET healthcheck ok      # write succeeds again

Longer term the producer was changed to use a capped Redis Stream (XADD ... MAXLEN ~ 100000) and every session key was given a TTL.

Prevention Best Practices

  • Set maxmemory explicitly (never leave it 0/unlimited on a shared host) with headroom below the container/host RAM for RSS and fragmentation.
  • Choose maxmemory-policy deliberately: allkeys-lru/allkeys-lfu for caches, noeviction only for datastores where losing a key is unacceptable — and then size for the full dataset.
  • Give cache keys a TTL; monitor expires vs keys in INFO keyspace.
  • Alert on used_memory / maxmemory ratio and on evicted_keys rising unexpectedly.
  • Scan periodically with redis-cli --bigkeys and cap collections (LTRIM, stream MAXLEN, hash field limits).
  • Watch mem_fragmentation_ratio; enable activedefrag yes when it stays high.
  • Feed the INFO memory output into the free incident assistant, and browse more Redis guides.

Quick Command Reference

# Limit, policy, and current usage
redis-cli INFO memory | grep -E 'used_memory_human|maxmemory_human|maxmemory_policy|mem_fragmentation_ratio'
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy

# Where did the memory go?
redis-cli --bigkeys
redis-cli INFO keyspace
redis-cli MEMORY DOCTOR
redis-cli MEMORY USAGE <key>

# Eviction / expiry stats
redis-cli INFO stats | grep -E 'evicted_keys|expired_keys'

# Fixes
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG SET maxmemory 6gb
redis-cli CONFIG REWRITE

Conclusion

OOM command not allowed when used memory > 'maxmemory' means the instance is full and the policy will not evict. The typical root causes are:

  1. maxmemory reached while on noeviction.
  2. Keys written without TTLs, so the dataset grows unbounded.
  3. A handful of big keys dominating memory.
  4. High fragmentation inflating RSS.

Don’t just raise maxmemory — confirm the policy fits the workload (cache vs. datastore), find the keys that filled the instance with --bigkeys and INFO keyspace, and cap unbounded growth so the ceiling is never hit by accident again.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.