Redis keeps everything in RAM. Without a limit, it grows until the server runs out of memory and the kernel’s OOM killer steps in — often killing Redis itself or your database. maxmemory caps Redis’s memory, and the eviction policy decides what happens when the cap is reached.
Set a limit
/etc/redis/redis.conf:
maxmemory 512mb
maxmemory-policy allkeys-lru
Or at runtime (and persist it with CONFIG REWRITE):
redis-cli CONFIG SET maxmemory 512mb
redis-cli CONFIG SET maxmemory-policy allkeys-lru
redis-cli CONFIG REWRITE
How much?
- Leave room for the OS, your app and database.
- If persistence (RDB/AOF rewrite) is enabled, background saves fork the process; on write-heavy instances memory can temporarily rise significantly. Keep headroom — see Redis persistence.
maxmemorycounts dataset memory; actual process memory (RSS) is higher due to allocator overhead and fragmentation.
On a 2 GB VPS running a web stack, 128–256 MB for a cache is typical.
Eviction policies
| Policy | Evicts | Use for |
|---|---|---|
noeviction |
Nothing — writes fail with an OOM error when full | Data you can’t lose: queues, primary data |
allkeys-lru |
Least recently used keys, any key | General-purpose cache (most common) |
allkeys-lfu |
Least frequently used keys | Caches with stable “hot” items |
allkeys-random |
Random keys | Rarely ideal |
volatile-lru |
LRU among keys with a TTL | Mixed use: cache keys have TTLs, persistent keys don’t |
volatile-lfu |
LFU among keys with a TTL | Same, frequency-based |
volatile-ttl |
Keys with the shortest remaining TTL | When TTL reflects importance |
volatile-random |
Random keys with a TTL | Rarely ideal |
The default is noeviction. For a cache that’s the wrong choice: when full, every write fails and your application starts erroring.
volatile-* caveat: if no keys have a TTL, nothing can be evicted and Redis behaves like noeviction.
LRU and LFU are approximated by sampling (maxmemory-samples, default 5); raising it to 10 makes eviction more accurate at a small CPU cost.
Choosing for common setups
- WordPress/Laravel object cache, page cache, API response cache →
allkeys-lru(orallkeys-lfu). - Sessions → enough memory to not evict;
noevictionorvolatile-lruwith session TTLs, so active sessions aren’t dropped. - Queues (Sidekiq, Celery, BullMQ) →
noeviction— losing jobs silently is worse than a visible error. Size memory generously and monitor. - One Redis for cache and queues → better to run two Redis instances (or databases with separate servers) with different policies; one
maxmemoryapplies to the whole instance.
Monitor
redis-cli INFO memory | grep -E 'used_memory_human|maxmemory_human|mem_fragmentation_ratio'
redis-cli INFO stats | grep -E 'evicted_keys|keyspace_hits|keyspace_misses'
- evicted_keys rising quickly → cache too small for the working set (hit ratio drops); increase
maxmemoryor cache less. - mem_fragmentation_ratio well above 1.5 → fragmentation; Redis’s
activedefrag yescan help. - Hit ratio = hits / (hits + misses).
Find what uses memory:
redis-cli --bigkeys
redis-cli --memkeys
redis-cli MEMORY USAGE some:key
Use TTLs anyway
Even with LRU eviction, set expirations on cache entries (SET key value EX 3600). Stale data disappears on its own, memory stays predictable, and volatile-* policies become usable.
OOM errors from Redis
OOM command not allowed when used memory > 'maxmemory'
With noeviction, this is Redis protecting data. Increase memory, reduce stored data, or switch to an eviction policy if the data is cache.
Related: installing Redis, redis-cli commands and WordPress Redis object cache.