Example: Increase maxmemory to 4 Gigabytes (4294967296 bytes)

There is a specific kind of dread that washes over a developer when their application suddenly halts in the middle of the night, and the logs start screaming OOM command not allowed when used memory > 'maxmemory'.

I’ve been woken up by this exact Redis Out of Memory (OOM) error more times than I care to admit. On one memorable occasion, a junior developer pushed a feature that cached user sessions indefinitely without a Time-To-Live (TTL). Within three hours, our primary Redis instance hit its memory ceiling, and every subsequent write request was met with a cold, hard refusal from the database.

If you are currently staring at this error, take a deep breath. Your data is likely still safe, but Redis has simply locked the vault door to protect itself (and your server) from crashing entirely.

In this comprehensive guide, we are going to walk through exactly how to fix redis oom command not allowed. We will cover the root cause analysis, provide step-by-step solutions ranging from immediate triage to edge cases, and lay out a battle plan to ensure you never get paged for this issue again.

Understanding the Root Cause of the Redis OOM Error

Before we start fixing things, we need to understand why Redis throws this specific error.

Redis is an in-memory data store. By design, it tries to hold all your dataset in RAM for lightning-fast access. However, if you are running an open-source version of Redis, you are likely bound by the maxmemory directive defined in your redis.conf file (or via your cloud provider’s plan limits).

When Redis reaches this maxmemory limit, it checks the maxmemory-policy configuration. This policy tells Redis what to do when it runs out of space.

If your policy is set to noeviction, Redis will simply refuse any command that takes up more memory (like SET, HSET, LPUSH, etc.). Read commands (GET, HGET) will usually still work, but your application’s write functionality will grind to a halt, returning the dreaded OOM command not allowed when used memory > 'maxmemory'.

Step-by-Step Triage: Immediate Fixes

When your production environment is down, you don’t have time to read a novel. You need to stop the bleeding. Here are the most common and immediate ways to resolve the issue.

Step 1: Inspect Your Eviction Policy

The most frequent culprit behind this error is an improperly configured eviction policy. Many modern cloud providers (like AWS ElastiCache or Google Cloud Memorystore) default to noeviction to prevent accidental data loss. However, if you are using Redis as a cache, this is the exact opposite of what you want.

Connect to your Redis instance using the redis-cli and check your current memory policy:

redis-cli CONFIG GET maxmemory-policy

If the response is noeviction, you have found your smoking gun.

The Fix:
If your Redis instance is strictly being used for caching (meaning the source of truth lives in a persistent database like PostgreSQL or MySQL), you should change this policy to automatically evict old data.

Run the following command to change the policy on the fly:

redis-cli CONFIG SET maxmemory-policy allkeys-lru

Note: allkeys-lru (Least Recently Used) will evict the oldest untouched keys to make room for new ones. If you are using Redis as a queue or for persistent data, do not use this approach without understanding the data loss implications.

Step 2: Find and Remove Memory Hogs

Sometimes your eviction policy is correct, but a single massive key is consuming a disproportionate amount of your memory. I once debugged a system where a developer was appending user analytics to a single, massive Redis List. Over months, this list grew to consume 2.5 GB of a 3 GB instance.

You can use the MEMORY DOCTOR command (available in Redis 4.0+) to get a quick summary of potential issues:

redis-cli MEMORY DOCTOR

For a more hands-on approach, use the --bigkeys flag to scan the keyspace and identify the largest data structures:

redis-cli --bigkeys

This command will output a report showing the largest String, List, Set, Sorted Set, and Hash in your database.

The Fix:
If you find an abnormally large key that is no longer needed, or is safe to clear, you can delete it to immediately free up a massive chunk of memory:

redis-cli UNLINK massive_log_key_123

(Pro-tip: Always use UNLINK instead of DEL for large keys. UNLINK deletes the key asynchronously in a background thread, preventing your main Redis thread from blocking and causing latency spikes).

Step 3: Increase the maxmemory Limit

If your application genuinely needs to store more data, and your server actually has more physical RAM available, you can simply raise the maxmemory limit.

First, check your current limit:

redis-cli CONFIG GET maxmemory

If you have spare RAM on the server (which you can check by running htop or free -m on the Linux host), you can increase the limit dynamically:

# Example: Increase maxmemory to 4 Gigabytes (4294967296 bytes)
redis-cli CONFIG SET maxmemory 4gb

Important Warning: A golden rule of database administration is to never let Redis consume 100% of your system’s physical RAM. Redis requires memory to perform background saves (creating .rdb files) and to handle client output buffers. If Redis hits the hardware ceiling, the Linux Out-Of-Memory (OOM) Killer will step in and aggressively terminate the Redis process. Always leave at least 20-30% of your server’s RAM free.

Step 4: Fix Application-Level Memory Leaks (Missing TTLs)

If you have fixed the immediate crisis, the next step is ensuring it doesn’t happen again. The most common reason caches grow indefinitely is that developers forget to set an Expiration Time (TTL).

If you pump data into Redis without a TTL, it will sit there forever. Let’s look at a common pattern in Python using the redis-py library:

The Bad Code:

import redis

r = redis.Redis(host='localhost', port=6379, decode_responses=True)

# Saving a user session without a TTL. It will stay here forever!
r.set('user:1001:session', '{"data": "logged_in"}') 

The Fix (Copy-Paste Ready Code):
Always explicitly declare a TTL when using Redis for ephemeral data like caches or sessions.

import redis

r = redis.Redis(host='localhost', port=6379, decode_responses=True)

# Set the session with a 30-minute (1800 seconds) expiration
r.set('user:1001:session', '{"data": "logged_in"}', ex=1800)

You can also audit your existing database to find keys that are missing TTLs. While Redis doesn’t have a native “find keys without TTL” command, you can write a quick Lua script to scan for them:

redis-cli --eval find_no_ttl.lua

find_no_ttl.lua contents:

local cursor = '0'
local no_ttl_keys = {}
local count = 0

repeat
    local reply = redis.call('SCAN', cursor, 'COUNT', 1000)
    cursor = reply[1]
    local keys = reply[2]

    for i, key in ipairs(keys) do
        -- Ignore Redis internal keys
        if string.sub(key, 1, 1) ~= '_' then
            local ttl = redis.call('TTL', key)
            if ttl == -1 then
                table.insert(no_ttl_keys, key)
                count = count + 1
                -- Safety break so we don't print thousands of lines at once
                if count > 100 then
                    return no_ttl_keys
                end
            end
        end
    end
until cursor == '0'

return no_ttl_keys

Advanced Troubleshooting: Edge Cases

If you have applied the immediate fixes above and you are still searching for how to fix redis oom command not allowed, you might be dealing with an architectural edge case.

Edge Case 1: Client Output Buffer Exhaustion

Redis uses memory not just to store your data, but to buffer the responses it sends back to connected clients. If a client (like a slow consumer in a Pub/Sub setup, or a delayed replica) cannot read data fast enough, Redis will keep the unsent data in a memory buffer.

If this buffer grows out of control, it can trigger an OOM condition.

Check your client connections using:

redis-cli CLIENT LIST

Look at the omem (output buffer memory) column. If you see a client with an incredibly high omem value, that client is struggling to process data.

The Fix:
1. Kill the misbehaving client: redis-cli CLIENT KILL ADDR <ip:port>
2. Review your application’s consumer logic to ensure it processes messages efficiently.
3. Tune the client-output-buffer-limit in your redis.conf to force Redis to disconnect slow clients before they crash the server.

Edge Case 2: Lua Script Memory Leaks

If your application relies heavily on Redis Lua scripts, you need to be careful with how you manage memory inside the scripts.

A common mistake is defining large global tables inside a Lua script. Because Redis

Leave a Reply

Your email address will not be published. Required fields are marked *