← Debugging Guides

阅读中文版本

Redis OOM command not allowed — maxmemory with noeviction

Fix "OOM command not allowed when used memory > maxmemory" by choosing an eviction policy, setting maxmemory, and sizing the instance.

intermediatedebuggingredismemoryeviction

Symptoms

  • Writes fail with "OOM command not allowed when used memory > 'maxmemory'"
  • Reads still work while writes are rejected
  • Memory fills gradually until writes stop

Possible causes

  • maxmemory is set but the policy is noeviction, so Redis refuses writes instead of evicting
  • The working set genuinely exceeds the configured memory
  • Big keys or no TTLs let memory grow without bound

Diagnosis steps

Check memory and policy

redis-cli INFO memory | grep used_memory_human; redis-cli CONFIG GET maxmemory-policy maxmemory

Interpretation

A used_memory at maxmemory with policy noeviction explains the rejected writes.

Find large keys

redis-cli --bigkeys

Interpretation

Oversized keys or missing TTLs often account for the memory growth.

Root cause

With maxmemory set and policy noeviction, Redis rejects write commands once the limit is reached to avoid data loss. This is a deliberate safety mode, not a bug, so either allow eviction or provide more memory.

Fix

Set an appropriate eviction policy (allkeys-lru for a cache, volatile-ttl for expiring data), keep noeviction only when data must not be lost, add TTLs, split big keys, and size the instance to the working set.

Risk note

An eviction policy silently discards keys; for data that must persist, use noeviction and provision memory, not eviction.

Verify the fix

After tuning, confirm writes succeed and used_memory stays below maxmemory; verify evicted_keys or expired_keys move as expected.

Symptoms

This guide profiles the failure behind “Redis OOM command not allowed — maxmemory with noeviction”. It walks through the observable symptoms, a reproducible diagnosis path, the underlying root cause, the concrete fix, and how to verify the change and prevent a regression.

Observed symptoms include:

  • Writes fail with “OOM command not allowed when used memory > ‘maxmemory’”
  • Reads still work while writes are rejected
  • Memory fills gradually until writes stop

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Check memory and policy

redis-cli INFO memory | grep used_memory_human; redis-cli CONFIG GET maxmemory-policy maxmemory

A used_memory at maxmemory with policy noeviction explains the rejected writes.

Step 2: Find large keys

redis-cli --bigkeys

Oversized keys or missing TTLs often account for the memory growth.

Likely contributors, in order of frequency:

  • maxmemory is set but the policy is noeviction, so Redis refuses writes instead of evicting
  • The working set genuinely exceeds the configured memory
  • Big keys or no TTLs let memory grow without bound

Root Cause

With maxmemory set and policy noeviction, Redis rejects write commands once the limit is reached to avoid data loss. This is a deliberate safety mode, not a bug, so either allow eviction or provide more memory.

The Fix

Set an appropriate eviction policy (allkeys-lru for a cache, volatile-ttl for expiring data), keep noeviction only when data must not be lost, add TTLs, split big keys, and size the instance to the working set.

Watch out: An eviction policy silently discards keys; for data that must persist, use noeviction and provision memory, not eviction.

# size the limit and choose a cache-friendly policy
redis-cli CONFIG SET maxmemory 2gb
redis-cli CONFIG SET maxmemory-policy allkeys-lru

# add TTLs so data expires instead of accumulating
redis-cli SET session:1 data EX 3600

# inspect
redis-cli INFO stats | grep -E 'evicted_keys|expired_keys'

Verify and Prevent

After tuning, confirm writes succeed and used_memory stays below maxmemory; verify evicted_keys or expired_keys move as expected.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.