What's Actually Happening

When Redis reaches its configured maxmemory limit, it either evicts keys based on policy or rejects writes with OOM error. If eviction can't free memory or is disabled, you get memory allocation errors.

The Error You'll See

bash
OOM command not allowed when used memory > 'maxmemory'.

Or in application logs:

bash
redis.exceptions.ResponseError: OOM command not allowed when used memory > 'maxmemory'.

Why This Happens

  1. 1.maxmemory too low - Limit set too low for workload
  2. 2.No eviction policy - volatile-lru not configured
  3. 3.No expiring keys - All keys persistent, nothing to evict
  4. 4.Large objects - Individual values too large
  5. 5.Memory fragmentation - Fragmentation wasting memory

Step 1: Check Memory Usage

bash
redis-cli info memory

Key fields:

bash
used_memory:1073741824         # Bytes used
used_memory_human:1.00G        # Human readable
used_memory_peak:2147483648    # Peak usage
maxmemory:1073741824           # Configured limit
maxmemory_human:1.00G
maxmemory_policy:noeviction    # Eviction policy

If used_memory >= maxmemory, Redis is at limit.

Step 2: Check Current Maxmemory Setting

```bash redis-cli config get maxmemory # 1) "maxmemory" # 2) "1073741824" # 1GB in bytes

redis-cli config get maxmemory-policy # 1) "maxmemory-policy" # 2) "noeviction" ```

Step 3: Increase Maxmemory

```bash # Increase to 2GB redis-cli config set maxmemory 2147483648

# Or set to 0 for no limit (not recommended) redis-cli config set maxmemory 0

# Persist change redis-cli config rewrite ```

Or edit config file:

```bash sudo vim /etc/redis/redis.conf

maxmemory 2gb ```

Step 4: Configure Eviction Policy

Choose appropriate policy:

PolicyDescription
noevictionReturn error when memory limit reached
allkeys-lruRemove least recently used keys
volatile-lruRemove LRU among keys with expire set
allkeys-randomRemove random keys
volatile-randomRemove random keys with expire set
volatile-ttlRemove keys with shortest TTL

Set policy:

```bash # Recommended: allkeys-lru for cache redis-cli config set maxmemory-policy allkeys-lru

# Persist redis-cli config rewrite ```

Step 5: Check for Keys Without Expiry

bash
# Count keys without TTL
redis-cli --scan | while read key; do
  ttl=$(redis-cli ttl "$key")
  if [ "$ttl" -eq -1 ]; then
    echo "$key"
  fi
done | wc -l

If many keys without TTL and using volatile-lru, eviction won't work.

Step 6: Analyze Memory Usage by Key

```bash # Use Redis MEMORY command (Redis 4.0+) redis-cli memory usage mykey

# Sample memory usage of keys redis-cli --sample-keys 1000 memory usage ```

Step 7: Find Large Keys

```bash # Find keys using most memory redis-cli --bigkeys

# Output: # Sampled 1000 keys # Biggest string: 'large-key' (1048576 bytes) # Biggest list: 'my-list' (10000 items) ```

Step 8: Check Memory Fragmentation

bash
redis-cli info memory | grep fragmentation

Output:

bash
mem_fragmentation_ratio:1.50  # 1.5x fragmentation

If ratio > 1.5, significant fragmentation. Restart Redis to defragment, or use active defragmentation:

bash
redis-cli config set activedefrag yes

Step 9: Delete Unused Keys

```bash # Delete keys matching pattern (careful!) redis-cli --scan --pattern "cache:*" | xargs redis-cli del

# Set expiry on keys redis-cli expire mykey 3600

# Flush database (nuclear option) redis-cli flushdb ```

Step 10: Upgrade Redis for Better Memory Management

Redis 4.0+ has active defragmentation. Redis 5.0+ has improved algorithms.

bash
redis-cli info server | grep redis_version

Verify the Fix

```bash # Check memory usage redis-cli info memory | grep used_memory_human

# Check eviction is working redis-cli info stats | grep evicted_keys

# Test writes work redis-cli set test "hello" # OK ```

Prevention Tips

```bash # Set appropriate maxmemory (leave room for OS) maxmemory 4gb # On 8GB server

# Use allkeys-lru for cache workloads maxmemory-policy allkeys-lru

# Set TTL on keys SET mykey value EX 3600 # Expire in 1 hour

# Monitor memory usage # Alert when used_memory > 80% of maxmemory ```