Resolving Redis OOM: ‘command not allowed when used memory limit reached’ on Debian 12 Bookworm
Troubleshoot and resolve Redis 'OOM command not allowed' errors on Debian 12 Bookworm. Learn to optimize memory, adjust limits, and prevent service disruptions.
Troubleshoot and resolve Redis 'OOM command not allowed' errors on Debian 12 Bookworm. Learn to optimize memory, adjust limits, and prevent service disruptions.
When your application relies on Redis as a cache or a primary data store, encountering an "OOM command not allowed" error can bring your services to a grinding halt. This critical error indicates that your Redis instance has exhausted its configured memory limit and is actively preventing write operations or even read operations, depending on your policy. For web applications, this often manifests as slow responses, HTTP 500 errors, or complete service unavailability.
This guide provides a comprehensive, step-by-step approach to diagnose and resolve this issue on Debian 12 Bookworm, leveraging expert SysAdmin and DevOps practices.
Symptom & Error Signature
Users will typically experience application slowdowns or outright failures. Developers might see exceptions in their application logs indicating a problem connecting to Redis or executing commands.
The most direct symptom is Redis refusing commands when accessed via redis-cli or through an application's Redis client library.
Example Application Log Output (Python/Django with Redis Cache):
Traceback (most recent call last):
File "/app/env/lib/python3.11/site-packages/redis/connection.py", line 1253, in send_packed_command
self.send_response(connection, command_name, **options)
File "/app/env/lib/python3.11/site-packages/redis/connection.py", line 1257, in send_response
raise RedisError(response)
redis.exceptions.RedisError: OOM command not allowed when used memory > 'maxmemory'.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/app/my_app/views.py", line 42, in my_view
cache.set('my_data', complex_computation(), timeout=300)
File "/app/env/lib/python3.11/site-packages/django_redis/cache.py", line 98, in set
return self.client.set(key, self.encode(value), timeout, nx=nx, xx=xx)
File "/app/env/lib/python3.11/site-packages/redis/client.py", line 1928, in set
return self.execute_command('SET', *args)
File "/app/env/lib/python3.11/site-packages/redis/client.py", line 1056, in execute_command
return self._execute_command(conn, conn.send_packed_command(command, *args))
File "/app/env/lib/python3.11/site-packages/redis/client.py", line 93, in _execute_command
raise RedisError(e)
redis.exceptions.RedisError: OOM command not allowed when used memory > 'maxmemory'.
Example redis-cli Output:
$ redis-cli
127.0.0.1:6379> set mykey myvalue
(error) OOM command not allowed when used memory > 'maxmemory'.
127.0.0.1:6379> get mykey
"myvalue"
# Note: Reads might still work initially, but writes are blocked.
# Depending on maxmemory-policy, reads might also eventually be impacted.
Example Redis Server Log Output (/var/log/redis/redis-server.log or journalctl -u redis):
8192:M 10 Sep 2026 14:35:01.123 # WARNING: OOM command not allowed. Used memory > maxmemory.
8192:M 10 Sep 2026 14:35:01.124 # Client id=123 addr=127.0.0.1:45678 fd=9 name=my-app-client age=10 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf_free=0 obl=0 oll=0 omem=0 events=r cmd=set scheduled to be killed because OOM.
Root Cause Analysis
The "OOM command not allowed" error in Redis is a direct consequence of the Redis instance attempting to use more memory than its configured maxmemory limit. When this threshold is breached, Redis, by default, enters a protective state to prevent the entire system from running out of memory and potentially crashing.
Here's a deeper look into the underlying reasons:
maxmemoryDirective Exceeded:- Redis is configured with a
maxmemorydirective in its configuration file (redis.conf). This parameter defines the maximum amount of RAM that Redis is allowed to consume. - When
used_memory(reported byINFO memory) grows beyondmaxmemory, Redis activates itsmaxmemory-policy.
- Redis is configured with a
maxmemory-policy(Crucial Configuration):- This directive dictates Redis's behavior when
maxmemoryis reached.noeviction(Default): This is the most common cause of the "OOM command not allowed" error. Whenmaxmemoryis reached, Redis will not evict any keys. Instead, it will refuse all write commands (and sometimes even reads depending on internal operations) with the OOM error. This policy ensures data integrity but prioritizes stability over availability when memory is full.- Eviction Policies (e.g.,
allkeys-lru,volatile-lru,allkeys-random): These policies instruct Redis to automatically evict (delete) keys whenmaxmemoryis reached to free up space for new data. If an appropriate eviction policy is set, you might not see the "OOM command not allowed" error as frequently, but instead, observe cache misses due to data being evicted.
- This directive dictates Redis's behavior when
Memory Pressure from Data Growth:
- Increased Workload: A surge in application usage, more users, or new features that store more data in Redis can naturally lead to increased memory consumption.
- Inefficient Data Structures: Storing large lists, sets, or complex hash structures without proper optimization can lead to disproportionate memory usage. Large key sizes or numerous small keys also contribute.
- Memory Leaks (Application/Redis): While rare in Redis itself, application-level issues might continuously add data to Redis without proper expiration, or a bug in Redis could cause memory to be held onto unnecessarily.
Persistence Overhead (RDB/AOF):
- When Redis performs background saves (RDB) or AOF rewrites, it forks a child process. This child process shares the parent's memory pages using copy-on-write semantics. However, if the parent Redis process modifies data while the child is saving, the modified pages are duplicated, temporarily increasing the overall memory footprint of the Redis instance and the system. This "copy-on-write" overhead can push Redis over its
maxmemorylimit.
- When Redis performs background saves (RDB) or AOF rewrites, it forks a child process. This child process shares the parent's memory pages using copy-on-write semantics. However, if the parent Redis process modifies data while the child is saving, the modified pages are duplicated, temporarily increasing the overall memory footprint of the Redis instance and the system. This "copy-on-write" overhead can push Redis over its
Insufficient System Memory:
- The Redis
maxmemorymight be set appropriately for Redis, but the server itself might not have enough total RAM to accommodate Redis plus other services (e.g., application servers, databases, operating system overhead). This leads to system-level OOM issues, potentially affecting Redis.
- The Redis
Step-by-Step Resolution
Follow these steps to diagnose and resolve the "OOM command not allowed" error on your Debian 12 server.
1. Verify Current Redis Memory Usage and Configuration
First, gather information about Redis's current state and its configuration.
# Check Redis service status
sudo systemctl status redis
# Connect to redis-cli and get memory information
redis-cli info memory
Look for these key metrics in the INFO memory output:
used_memory_human: The amount of memory Redis is currently using (human-readable).used_memory_rss_human: The resident set size, memory held by the operating system (can be higher thanused_memorydue to fragmentation, copy-on-write, etc.).maxmemory_human: The configured maximum memory limit for Redis.maxmemory_policy: The current eviction policy.
Next, inspect the Redis configuration file for the maxmemory and maxmemory-policy directives. The default location on Debian 12 is usually /etc/redis/redis.conf.
# Locate the Redis configuration file
sudo find / -name "redis.conf" 2>/dev/null
# Typically it's /etc/redis/redis.conf on Debian
# Inspect maxmemory and maxmemory-policy
grep -E "maxmemory|maxmemory-policy" /etc/redis/redis.conf
Example Output:
# maxmemory <bytes>
maxmemory 2gb
maxmemory-policy noeviction
If maxmemory is commented out or missing, Redis will use all available system memory, making it prone to system-wide OOM issues if not explicitly managed. If maxmemory-policy is noeviction, this directly explains why commands are being blocked.
2. Clear Non-Essential Data (Temporary Relief – Use with CAUTION)
If you need immediate relief and can afford to lose some or all cached data, you can clear data from Redis.
FLUSHALLwill delete ALL keys from ALL databases in Redis. This is a destructive operation and should only be used if you understand the implications and can rebuild your data or if Redis is purely used as an ephemeral cache. Consider theFLUSHDBcommand if you only want to clear the currently selected database.
# Connect to redis-cli
redis-cli
# Option 1: Delete all keys from all databases (HIGHLY DESTRUCTIVE)
127.0.0.1:6379> FLUSHALL
# Option 2: Delete all keys from the current database (still destructive, but targeted)
127.0.0.1:6379> SELECT 0 # Select database 0 if not already selected
127.0.0.1:6379> FLUSHDB
# Option 3: Delete specific keys if you know which ones are problematic
# (Identify using redis-cli --bigkeys or application logs)
127.0.0.1:6379> DEL my:large:key another:problematic:set
After flushing, Redis memory usage should drop, and commands should be allowed again. This is a temporary fix and does not address the underlying cause.
3. Adjust Redis maxmemory Limit
Increasing the maxmemory limit is often the quickest way to resolve the OOM error, but it's crucial to do so responsibly. Over-allocating memory to Redis can starve other essential services on your server.
Calculation:
Consider the total RAM of your server. Allocate typically 50-70% of available RAM to Redis, reserving the rest for the OS, your application, and other services. Also, factor in the copy-on-write overhead for RDB/AOF persistence, which can temporarily double Redis's used_memory in worst-case scenarios.
Example: If your server has 8GB RAM and Redis is the primary service, you might set maxmemory to 4gb or 5gb.
Edit the Redis configuration file:
sudo nano /etc/redis/redis.confFind the
maxmemorydirective. Uncomment it if it's commented out, or modify its value.# Old configuration example: # maxmemory <bytes> # maxmemory-policy noeviction # New configuration example (e.g., for 4GB): maxmemory 4gb maxmemory-policy noeviction # Keep noeviction for now, we'll address it nextYou can specify memory in bytes,
kb,mb, orgb.Save the file and restart Redis:
sudo systemctl restart redis
Do not set
maxmemoryto a value close to your server's total RAM. This can lead to the entire system running out of memory, causing kernel OOM killer to terminate processes (including Redis or your application), leading to severe instability. Always leave ample RAM for the operating system, kernel, and other running applications.
4. Optimize maxmemory-policy
If your Redis instance is primarily used as a cache where some data loss is acceptable for the sake of continuous availability, changing the maxmemory-policy is essential.
Understand
maxmemory-policyoptions:noeviction: (Default) Refuse writes when memory limit is reached. No keys are evicted.allkeys-lru: Evict keys with an LRU (Least Recently Used) algorithm among all keys. This is generally a good choice for a general-purpose cache.volatile-lru: Evict keys with an LRU algorithm among only those keys that have an expiration set.allkeys-lfu: Evict keys with an LFU (Least Frequently Used) algorithm among all keys.volatile-lfu: Evict keys with an LFU algorithm among only those keys that have an expiration set.allkeys-random: Evict random keys among all keys.volatile-random: Evict random keys among only those keys that have an expiration set.volatile-ttl: Evict keys with the shortest remaining TTL (Time To Live) among only those keys that have an expiration set.
Edit the Redis configuration file:
sudo nano /etc/redis/redis.confChange
maxmemory-policyto an appropriate eviction policy. For most caching scenarios,allkeys-lruis a solid choice.# Example: maxmemory 4gb maxmemory-policy allkeys-lruSave the file and restart Redis:
sudo systemctl restart redis
Choosing an eviction policy implies that Redis will automatically delete data when the memory limit is reached. Ensure your application can gracefully handle missing keys (cache misses) and that the evicted data is truly disposable or can be easily regenerated. If Redis is your primary data store and data loss is unacceptable, you must use
noevictionand instead scale up memory or optimize data structures (Steps 5 and 6).
5. Analyze and Optimize Application Data Structures
Often, the problem isn't just the maxmemory limit, but how your application uses Redis.
Identify Large Keys: Use
redis-cli --bigkeysto find keys consuming the most memory. This command will sample your dataset and report the top keys by data type.redis-cli --bigkeysExample Output:
# Scanning the entire keyspace to find biggest keys as well as # average key size. You can use -i 0.1 to sleep 0.1 sec per 100 # keys to avoid blocking your server for too long. [... snip ...] Biggest string key: user:session:12345 (2000000 bytes) Biggest list key: recent:activities (10000 elements) (80000 bytes) Biggest hash key: product:details:9876 (5000 fields) (60000 bytes)Review Application Code:
- Serialization: Are you efficiently serializing data? Using JSON, MessagePack, or custom binary formats can greatly impact memory usage. For example, storing complex Python objects directly via
picklecan be very inefficient. - Key Expiration (TTL): Are all temporary keys given a
TTL? If not, they will persist indefinitely, consuming memory. UseEXPIREorSETEX. - Data Structures:
- Are you using large
LISTs when aSETorZSETwould be more memory-efficient for unique items or ranked data? - Are you storing many small objects as individual keys when a
HASHcould group them and save memory overhead? - Consider using Redis Stream for time-series data instead of large lists.
- Are you using large
- Atomic Operations: Ensure your application isn't accidentally creating duplicate data or large intermediate structures that aren't cleaned up.
- Serialization: Are you efficiently serializing data? Using JSON, MessagePack, or custom binary formats can greatly impact memory usage. For example, storing complex Python objects directly via
Use
INFO commandstats: This command can show you which commands are being executed most frequently, which might point to areas for optimization in your application logic.redis-cli info commandstats
Optimizing data structures and implementing proper TTLs can significantly reduce memory footprint without increasing maxmemory.
6. Increase System Memory (Hardware Upgrade/VM Scale-up)
If, after all optimizations, your application genuinely requires more data to be held in Redis than your current server's capacity, the ultimate solution is to scale up your server's resources.
Monitor System-Wide Memory: Before increasing
maxmemoryor concluding you need more RAM, ensure your server isn't already experiencing system-level memory pressure.free -h htop # or topLook at
Mem(total system memory),used,free, andbuff/cache. Ifavailablememory is consistently low, andswapis heavily used, your system needs more RAM.Upgrade your server's RAM:
- For virtual machines (VMs) or cloud instances (AWS EC2, Azure VM, Google Cloud Compute Engine, DigitalOcean Droplet, etc.), this typically involves selecting a larger instance type or scaling up the allocated RAM.
- For bare-metal servers, this means purchasing and installing more physical RAM.
After increasing system memory, you can safely increase Redis's maxmemory limit in /etc/redis/redis.conf and restart the Redis service.
7. Implement Robust Monitoring
Proactive monitoring is key to preventing these OOM errors in the future.
Monitor Key Redis Metrics:
used_memoryandused_memory_rss: Track Redis's actual memory consumption.maxmemory: Monitor the configured limit.evicted_keys: If you have an eviction policy, track how many keys are being evicted. A high rate might indicate that Redis is too small for your workload.keyspace_hitsandkeyspace_misses: Understand your cache efficiency.rdb_changes_since_last_saveoraof_pending_bio_fsync: Relates to persistence overhead.
Tools:
- Prometheus and Grafana: A powerful combination for collecting, storing, and visualizing time-series data. Use
redis_exporterto expose Redis metrics to Prometheus. infocommand scripting: You can scriptredis-cli infoand push the data to a monitoring system.- Cloud Provider Monitoring: If hosting Redis in a managed service, leverage their built-in monitoring and alerting.
- Prometheus and Grafana: A powerful combination for collecting, storing, and visualizing time-series data. Use
Set Up Alerts: Configure alerts for when
used_memoryexceeds a certain percentage (e.g., 80-90%) ofmaxmemory. This gives you time to react before the "OOM command not allowed" error occurs.
8. Consider Redis Cluster or Sharding
For extremely large datasets or high traffic loads that exceed the capacity of a single Redis instance, consider horizontal scaling:
- Redis Cluster: The official solution for sharding your data across multiple Redis nodes, providing high availability and linear scalability.
- Application-level Sharding: Your application can manage distributing keys across multiple independent Redis instances.
This is a more advanced solution for very high-scale deployments but crucial to consider if vertical scaling (more RAM on a single server) becomes cost-prohibitive or technically limited.
Our Production Verification Guarantee
Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.