← Back to DevBytes

Fix Redis 'OOM command not allowed' Error: Complete Troubleshooting Guide

Understanding the Redis 'OOM command not allowed' Error

When working with Redis in production, one of the most common and disruptive errors developers encounter is β€œOOM command not allowed”. OOM stands for Out Of Memory. This error is raised when Redis reaches its configured maximum memory limit and is unable to serve write requests that would consume additional memory. Redis, by default, applies a strict no-eviction policy if a maxmemory limit is set, meaning it refuses commands that would increase memory usage instead of automatically deleting existing keys.

The error typically appears in client libraries as a Redis::CommandError (Ruby), redis.exceptions.ResponseError (Python), or a similar exception with the message:

OOM command not allowed when used memory > 'maxmemory'

This guide walks through the root cause, diagnostic steps, immediate fixes, application-level handling, and long-term best practices to permanently resolve the error and build resilient Redis-backed systems.

What Triggers the OOM Error Exactly?

Redis manages memory using the maxmemory configuration directive. Once the used memory exceeds this limit, Redis checks the active eviction policy. The default policy, noeviction, instructs Redis to reject any command that could result in additional memory consumption. This includes:

Read-only commands like GET, LRANGE, HGET, and EXISTS are usually allowed even when memory is exhausted. Also, DEL and other key-deletion commands work perfectly β€” they free memory, which is critical for recovery.

Why This Error Matters

An OOM error is not just a transient hiccup; it indicates that your Redis instance has hit a hard memory ceiling and cannot accept writes. For applications that rely on Redis for caching, session storage, real-time counters, or pub/sub persistence, this can lead to:

Understanding the OOM error is essential for anyone operating Redis as a primary data store, cache, or message broker.

Immediate Diagnostic Steps

Before applying fixes, confirm the current memory state and configuration.

1. Check Memory Usage and Limits

Connect to Redis via redis-cli and run:

INFO memory

Look for key fields:

# Memory
used_memory:2984000
used_memory_human:2.84M
used_memory_rss:5.12M
maxmemory:500000
maxmemory_human:500.00K
maxmemory_policy:noeviction
mem_allocator:jemalloc-5.1.0

If used_memory β‰₯ maxmemory, you're in OOM territory. Also note maxmemory_policy.

2. Verify Eviction Policy

CONFIG GET maxmemory-policy

Output will be something like:

1) "maxmemory-policy"
2) "noeviction"

If the policy is noeviction, any write exceeding maxmemory triggers the OOM error. If you see volatile-lru or allkeys-lru, the error would only appear if there are no eligible keys to evict (e.g., all keys have no expiry and policy is volatile-lru). We'll cover this nuance later.

3. Identify Memory Consumers

To understand what is using memory, use:

MEMORY STATS

Or the more detailed:

MEMORY DOCTOR

This will output suggestions and highlight large keys. You can also scan for biggest keys:

redis-cli --bigkeys

Often, a few excessively large strings, lists, or sets dominate memory. Client output buffers and replication buffers can also consume significant memory β€” check CLIENT LIST for omem (output memory) values.

How to Fix the OOM Error: Step-by-Step Solutions

The appropriate fix depends on your use case. Below are practical approaches, from temporary mitigation to permanent resolution.

Option 1: Increase maxmemory (If Resources Allow)

If the server has spare RAM, simply raise the limit. This is the quickest fix but may only delay the problem if your data grows unbounded.

CONFIG SET maxmemory 2gb

Or update redis.conf permanently:

maxmemory 2gb

After setting, verify with CONFIG GET maxmemory. Note that increasing maxmemory doesn't evict existing keys; it merely raises the ceiling.

Option 2: Change Eviction Policy (Allowing Automatic Key Removal)

If Redis is used purely as a cache and data loss is acceptable, switch to an evicting policy. The most common and effective is allkeys-lru, which evicts the least recently used keys across the entire dataset when memory is exceeded.

CONFIG SET maxmemory-policy allkeys-lru

To make it permanent, add to redis.conf:

maxmemory-policy allkeys-lru

Other policies include volatile-lru (only keys with an expiry set), allkeys-random, volatile-ttl, etc. Choose based on whether you can afford to lose non-expiring keys. Important: Changing the policy does not immediately evict keys; eviction only kicks in when the memory limit is hit again. Test by temporarily lowering maxmemory to trigger eviction and observe.

After switching, monitor cache hit ratios and adjust if necessary.

Option 3: Free Up Memory by Deleting Keys or Flushing Data

If you can identify unused or expired keys, delete them manually:

DEL user:session:12345

For bulk cleanup based on pattern (use with caution in production):

redis-cli --scan --pattern 'temp:*' | xargs redis-cli DEL

If the dataset is entirely non-critical cache data, you can flush the database (reset):

FLUSHDB   # for current database
FLUSHALL  # for all databases

Warning: FLUSHALL is irreversible and will cause a complete cache reset, potentially leading to a thundering herd on your backend.

Option 4: Optimize Memory Usage

Reduce per-key overhead and data sizes:

Option 5: Scale Horizontally with Redis Cluster or Sharding

If a single instance cannot hold the dataset, distribute keys across multiple Redis nodes using Redis Cluster or client-side sharding. Redis Cluster automatically splits keyspace and manages failover. This eliminates the single memory bottleneck but requires application changes.

Handling the OOM Error in Application Code

Even with preventive measures, occasional memory spikes can occur. Applications must catch the error gracefully and implement fallback logic.

Python (redis-py) Example

import redis
import time

def safe_set(key, value, max_retries=3):
    r = redis.Redis(host='localhost', port=6379, decode_responses=True)
    for attempt in range(max_retries):
        try:
            r.set(key, value)
            return True
        except redis.exceptions.ResponseError as e:
            if 'OOM command not allowed' in str(e):
                # Attempt to free memory by deleting a random expired key (if applicable)
                # or simply wait and retry if eviction policy changed asynchronously
                time.sleep(0.5)
                continue
            raise
    # After max retries, fallback to alternative storage or log critical alert
    return False

# Usage
success = safe_set('user:42:cart', '{"items": [...]}')
if not success:
    print("Redis write failed – falling back to database")

Node.js (ioredis) Example

const Redis = require('ioredis');
const redis = new Redis();

async function safeSet(key, value, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      await redis.set(key, value);
      return true;
    } catch (err) {
      if (err.message.includes('OOM command not allowed')) {
        // Optionally delete some less important keys here
        await new Promise(resolve => setTimeout(resolve, 200));
        continue;
      }
      throw err;
    }
  }
  return false;
}

General Retry and Circuit-Breaker Pattern

Don't retry indefinitely. Combine with exponential backoff and circuit breakers. If Redis is in OOM state, immediate retries will likely fail again. Use monitoring to trigger alerts so operations teams can intervene.

Best Practices to Avoid OOM Errors Completely

Advanced: Understanding Eviction Under the Hood

When the eviction policy is allkeys-lru, Redis samples a set of keys (configurable via maxmemory-samples) and evicts the least recently used one. It repeats this process until memory falls below the limit. This means eviction is not instant; a sudden burst of writes can still temporarily exceed maxmemory, but the engine will quickly catch up and evict. If your application sees a brief OOM error even with an eviction policy, it could be that all sampled keys were ineligible (e.g., volatile-lru with no volatile keys). In such cases, switch to allkeys-lru or ensure sufficient volatile keys exist.

Also note that maxmemory is a soft limit for some operations. Redis uses memory for replication buffers, client output buffers, and Lua scripts. These can push actual memory usage above maxmemory, but Redis will still try to enforce the limit for data-bearing commands.

Conclusion

The Redis OOM command not allowed error is a protective mechanism that prevents uncontrolled memory growth and system instability. By understanding your memory usage, setting appropriate limits, and selecting the right eviction policy, you can eliminate this error entirely or handle it gracefully in your application logic. Start by auditing your instance with INFO memory and MEMORY DOCTOR, then decide whether to increase limits, switch to an eviction-based cache policy, or scale horizontally. Finally, harden your application with retries and fallbacks to ensure that even during memory storms, your users experience minimal disruption. With these practices, Redis remains the fast, reliable backbone it was designed to be.

πŸš€ Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started β€” $23.99/mo
← Back to all articles