If your application suddenly logs OOM command not allowed when used memory > 'maxmemory', Redis is doing exactly what it was told to do: it has hit its memory limit and is refusing writes instead of evicting keys. The opposite failure is worse: no limit at all, Redis grows until the Linux OOM killer ends it, and your cache or queue disappears in one go. Both have the same root cause: a Redis maxmemory and eviction policy setup that nobody chose deliberately. This guide covers how the limit works, how to pick an eviction policy and how to size memory realistically. Everything here applies to Valkey as well.
What the OOM error actually means
Redis checks memory usage whenever a client runs a command that adds data. If usage is above maxmemory, Redis applies the configured maxmemory-policy. With the default policy, noeviction, nothing is evicted: the server "will return an error when you try to execute commands that cache new data", while reads keep working (Redis docs: key eviction).
So the error isn't a crash. It's Redis protecting itself. The question is whether that is the behaviour you want, and the answer depends on what you store in it.
First decide: is this Redis a cache or a database?
This is the decision everything else follows from.
- Pure cache (every key can be rebuilt from the real database): evicting keys is fine. You want Redis to drop old entries and keep accepting writes.
- Data you can't lose (sessions you don't want to drop, queues, rate limit counters, job state, anything without another copy): eviction silently deletes data. Here
noevictionplus enough memory and good alerts is the safer choice. An error you can see beats data quietly vanishing. - Both in one instance: this is where most surprises come from. The Redis docs suggest the
volatile-*policies for this mix, but also say you "should consider running two separate Redis instances" if possible. We agree: separate instances, separate limits, separate policies.
The eviction policies, in plain words
noeviction: never evict; return errors on writes when full. The default.allkeys-lru: evict the least recently used keys. The docs call it "a good default option if you have no reason to prefer any others" for caches where some keys are much hotter than others.allkeys-lfu: evict the least frequently used keys (Redis 4.0+). Often better when popularity matters more than recency.allkeys-random: evict random keys. Reasonable when all keys are accessed about equally.volatile-lru,volatile-lfu,volatile-random: the same, but only among keys that have a TTL.volatile-ttl: evict keys with a TTL that expire soonest.allkeys-lrm,volatile-lrm: least recently modified, added in Redis 8.6. Reads don't refresh the timestamp, only writes do. Valkey's documentation doesn't list these, so check your engine and version before using them (Valkey docs).
The trap: volatile-* policies behave like noeviction if no keys have a TTL. Teams set volatile-lru, forget that half the application writes keys without an expiry, and get OOM errors anyway. If you choose a volatile policy, check that the keys you expect to be evicted really have TTLs.
Redis LRU and LFU are approximations: Redis samples a few keys (maxmemory-samples, default 5) and evicts the best candidate among them. Raising the sample count to 10 gets closer to true LRU at some CPU cost. For most workloads 5 is fine.
Sizing maxmemory: why "all the RAM" is wrong
On 64-bit systems maxmemory defaults to 0, meaning no limit. That's how Redis ends up killed by the kernel. Set it explicitly, and leave room for things that are not your data:
- Overhead and fragmentation. The Redis admin guide says it directly: "if you think you have 10 GB of free memory, set it to 8 or 9" (Redis administration).
- Replication and AOF buffers. Memory for buffers waiting to go to replicas or the AOF file is not counted towards
maxmemory. With replication or persistence, leave some RAM free for them.INFO memoryshows the current amount asmem_not_counted_for_evict. - Fork during saves. When Redis writes an RDB snapshot or rewrites the AOF, it forks. In a write-heavy application, "Redis can use up to 2 times the memory normally used" during the save, because modified pages get copied. Size for this, or the save is exactly when the OOM killer strikes.
- Other processes on the box: monitoring agents, Sentinel, the OS page cache for persistence files.
The admin guide also recommends vm.overcommit_memory = 1 so background saves don't fail on fork(), and disabling Transparent Huge Pages, which can hurt memory usage and latency.
Diagnosing a Redis that is running out of memory
redis-cli INFO memory
redis-cli INFO stats
redis-cli MEMORY DOCTOR
redis-cli --bigkeys
used_memoryvsmaxmemory: how close you are to the limit.used_memory_rssandmem_fragmentation_ratio: if RSS is much higher than used memory, fragmentation is eating RAM. Active defragmentation (activedefrag) can help.evicted_keysandexpired_keys: are keys being evicted or expiring as expected?keyspace_hitsandkeyspace_misses: the hit ratio. A falling hit ratio together with many evictions means the cache is too small or the policy evicts the wrong keys.--bigkeysandMEMORY USAGE <key>: find the few huge keys (a list that never gets trimmed, a hash that collects every user forever) that are often the real cause.
What to do when it's happening right now
- If it's a pure cache, switching to an evicting policy at runtime is quick:
CONFIG SET maxmemory-policy allkeys-lru. Then persist it in the config file. - If it holds important data, do not switch to eviction in a panic: you would be deleting data to make the error go away. Raise
maxmemoryif the host really has free RAM, or scale up, then find out what grew. - Look for the key that exploded. A runaway list or set is common and fixing that one key often frees most of the memory.
- Check for keys without TTLs that were supposed to have them.
Prevent it from happening again
- Set
maxmemoryandmaxmemory-policyexplicitly on every instance. Defaults are not a decision. - Alert on memory usage relative to
maxmemory, onevicted_keysgrowing for data instances, and on rejected commands inINFO commandstats. These belong with the other early-warning signals in database metrics that predict incidents. - Give every cache key a TTL, unless there's a clear reason not to.
- Keep caches and important data in separate instances.
- If you're moving from Redis to Valkey, carry these settings over deliberately and test with production-like data; our Redis to Valkey migration guide covers the rest of the checklist.
Key takeaways
- "OOM command not allowed" means Redis reached
maxmemorywith the defaultnoevictionpolicy and is refusing writes. - Choose the policy by what you store: evict for pure caches,
noevictionplus alerts for data you can't lose. volatile-*policies only evict keys with a TTL; without TTLs they act likenoeviction.- Set
maxmemorybelow physical RAM: leave room for overhead, replication buffers and up to 2x memory during saves. - Monitor memory, evictions, hit ratio and big keys, and keep caches separate from important data.