InletDownload

Redis error OOM

OOM command not allowed when used memory > 'maxmemory'

Redis has reached its own memory limit (maxmemory) and its eviction policy can’t or won’t free space, so it refuses commands that would add data. Reads and deletes still work. Free memory, choose an eviction policy that fits your data, or raise the limit.

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

Tested on Redis 8.10.2 and Valkey 8.1.10 (temporary servers with a 2–3 MB maxmemory) · Updated 9 October 2026

What it means

Redis has a memory limit of its own, maxmemory. Before it runs a command that can add data (SET, INCR, LPUSH, HSET and so on), it compares the memory it uses with that limit. Over the limit, it first tries to evict keys under maxmemory-policy. If the policy is noeviction, or the policy finds nothing it’s allowed to remove, the command is refused with OOM and nothing changes.

It isn’t your machine running out of memory: it’s the limit someone configured. On 64-bit systems maxmemory is 0 (no limit) by default, so if you see this error, a limit was set: in redis.conf, on the command line, or by your hosting provider.

What still works while Redis is full:

  • Reads: GET, HGETALL, SCAN, INFO.
  • Commands that free memory or don’t add any: DEL, UNLINK, EXPIRE all worked in the test below, while INCR and LPUSH were refused.
  • Not transactions with a write in them: the queued write gets OOM and EXEC then fails with EXECABORT.
  • Not scripts that write: a Lua script stops at its first write that needs memory, with the same message plus the script’s SHA1 and line.

Near the limit the result can change from one command to the next, because client buffers count towards the total too: in a first test, a 100 KB SET was refused and a small SET straight after it went through.

Common causes

  1. noeviction with data that keeps growing. It’s the default policy in open-source Redis, and the right one when Redis holds data you can’t lose. It means writes fail once the data outgrows the limit.
  2. A volatile-* policy, but keys without a TTL. volatile-lru, volatile-lfu, volatile-random and volatile-ttl only evict keys that have an expiry. With none, they behave like noeviction. AWS ElastiCache and Redis Cloud both default to volatile-lru.
  3. Cache keys written without an expiry, so a cache never shrinks.
  4. A few very large keys: a list used as a queue that nothing drains, a stream without MAXLEN, a hash or set that only grows.
  5. A plan or node that’s too small. Managed services set maxmemory from the plan or node type. ElastiCache keeps back 25% of a node’s memory by default (reserved-memory-percent), so maxmemory is lower than the advertised size. Upstash rejects writes when a database reaches its maximum data size with eviction off, which is its default.

How to fix it

See how close to the limit you are

redis-cli INFO memory | grep -E '^(used_memory_human|used_memory_dataset|maxmemory_human|maxmemory_policy):'
redis-cli INFO keyspace
redis-cli INFO stats | grep evicted_keys

used_memory_dataset is the data itself; the rest of used_memory is overhead such as client buffers and the replication backlog. INFO keyspace shows how many keys have an expiry (db0:keys=3000,expires=1,…): if expires is near zero, a volatile-* policy has nothing to evict. A rising evicted_keys means eviction is working.

Find what takes the memory

redis-cli --memkeys          # samples every key, reports the largest of each type
redis-cli --bigkeys          # the same, by element count
redis-cli MEMORY USAGE <key> # bytes for one key, overhead included

Both scans use SCAN, so they don’t block the server, but they do read every key: run them off peak on a big database. MEMORY DOCTOR gives a written report on fragmentation and peaks (it needs at least 5 MB in use to say anything, and Redis Cloud doesn’t support it).

Free some space now

DEL and UNLINK work while Redis is full (UNLINK frees large values in the background). To remove a group of keys, iterate with SCAN and delete in batches rather than running KEYS:

redis-cli --scan --pattern 'cache:*' | xargs -n 500 redis-cli UNLINK

Choose an eviction policy that matches the data

  • Redis is a cache (everything can be rebuilt): allkeys-lru, or allkeys-lfu if a few keys are read far more than others. Writes never fail for lack of memory; old keys go instead.
  • Cache and permanent data in one server: give every cache key a TTL and use volatile-lru, or better, run two servers.
  • Redis holds data you can’t lose (queues, sessions, counters): keep noeviction and add memory.
redis-cli CONFIG SET maxmemory-policy allkeys-lru

That lasts until a restart; put maxmemory-policy allkeys-lru in redis.conf too (or run CONFIG REWRITE). On ElastiCache, set it in a custom parameter group; on Redis Cloud, in the database’s data eviction policy; on Upstash, turn eviction on for the database.

Raise the limit, leaving room

redis-cli CONFIG SET maxmemory 2gb

Don’t give Redis all of the machine’s memory: while it writes a snapshot it can use up to twice its normal memory under heavy writes, and maxmemory doesn’t count every buffer. On a hosted service, move to a larger plan or node; on ElastiCache, AWS advises against lowering reserved-memory-percent.

Reproduce it

A temporary Redis 8.10.2 container, filled with 3,000 strings of 1,000 bytes and a list of 20,000 numbers, then limited to 2 MB with the default noeviction policy:

docker run --rm -d --name seo-redis-oom redis:8 redis-server --maxmemory 2mb --maxmemory-policy noeviction
redis-cli CONFIG SET maxmemory 0      # load the data first
redis-cli CONFIG SET maxmemory 2mb

The server logged:

# WARNING: the new maxmemory value set via CONFIG SET (2097152) is smaller than the current memory usage (4842424). This will result in key eviction and/or the inability to accept new write commands depending on the maxmemory-policy.

Then SET greeting hello, INCR visits and LPUSH queue:jobs 1 each got:

(error) OOM command not allowed when used memory > 'maxmemory'.

GET cache:page:1 returned its value, and EXPIRE and DEL returned (integer) 1. A transaction and a script:

OK
(error) OOM command not allowed when used memory > 'maxmemory'.
(error) EXECABORT Transaction discarded because of previous errors.
(error) OOM command not allowed when used memory > 'maxmemory'. script: b3d17f5cc28d7b2933b03a28240a5ebd4e7f3392, on @user_script:1.

What the server reported:

used_memory_human:4.76M
used_memory_dataset:3377760
maxmemory_human:2.00M
maxmemory_policy:noeviction
# Keyspace
db0:keys=3000,expires=1,avg_ttl=59904,subexpiry=0

MEMORY USAGE gave 1055 bytes for one 1,000-byte string and 76325 for the list, and redis-cli --memkeys found the same two: Biggest list found "queue:jobs" has 76325 bytes.

With CONFIG SET maxmemory-policy volatile-lru, Redis evicted the one key that had a TTL (evicted_keys:1) and still refused the SET. With allkeys-lru the SET returned OK; evicted_keys went to 2620 and 367 keys were left.

A temporary Valkey 8.1.10 server with --maxmemory 3mb refused its 18th 100 KB SET with the same words: OOM command not allowed when used memory > 'maxmemory'.

In Inlet

Inlet shows the server’s message and links the error to this page. INFO memory and INFO keyspace show as tables in a query tab, and a namespace opens as a grid with each key’s type, TTL and size, so large keys and keys without an expiry stand out; you can edit TTLs and delete keys there too. On a connection tagged production, Inlet refuses writes and admin commands such as CONFIG SET before they’re sent.

Related

Sources