Configuring maxmemory in Redis
Estimating the Right Memory Limit
Since Redis is an in-memory data store, it's wise to allocate only enough memory for frequently accessed data. The 80/20 rule (Pareto principle) often applies: about 20% of the data handles 80% of the requests. If your backing database is 10 GB, you might set Redis to 2 GB.
However, real-world scenarios vary:
- E-commerce flash sales: hot products may be only 10% of the catalog.
- Personalized content systems: 20% might not provide 80% of traffic; 40–50% of data may be needed.
- Extreme performance (e.g., flash sales): you might load 100% of the relevant data into Redis.
Once you estimate the required memory, configure the maxmemory setting.
Setting the Maximum Memory
By default, Redis uses all available system memory. To protect against OOM situations in production, set a cap.
redis-cli CONFIG SET maxmemory 4gb
The maxmemory directive limits the memory used by Redis itself (data structures, buffers, metadata) but does not account for memory fragmentation.
Memory Eviction Policies
Deleting Expired Keys
Redis uses two mechanisms to remove expired keys:
- Lazy deletion: When a key is accessed, Redis checks its expiration. If expired, the key is removed immediately and the client receives no result.
- Periodic deletion: A background task runs periodically. The algorithm:
- Pick 20 random keys.
- If more than 25% of those are expired, repeat the process.
- If the deletion phase exceeds 25 ms, switch to a fast mode with a 1 ms time limit and run at most once every 2 seconds.
The frequency of the timer is controlled by the hz configuration (default 10, meaning 10 times per second).
Because both lazy and periodic deletions are probabilistic, some expired keys may persist. For deterministic eviction, Redis also offers explicit policies.
Eviction Policies (maxmemory-policy)
The policy is set via:
redis-cli CONFIG SET maxmemory-policy allkeys-lru
Redis supports the following categories:
No Eviction
- noeviction (default): When memory is exceeded, write requests fail with an error. Reads continue normally.
Eviction Based on Expiring Keys
volatile-lru: Evict the least recently used key among keys with an expiration set.volatile-random: Randomly evict an expiring key.volatile-ttl: Evict the key with the shortest remaining TTL (i.e., the closest to expiration).volatile-lfu: Evict the least frequently used key among expiring keys.
Eviction Based on All Keys
allkeys-lru: Evict the least recently used key from the entire key space.allkeys-random: Randomly evict any key.allkeys-lfu: Evict the least frequently used key overall.
How Redis Implements Approximate LRU
True LRU requires a global linked list (costly for millions of keys). Redis uses an approximated version:
- Each Redis object stores a timestamp (
lrufield) updated on access. - When eviction is needed, Redis samples a small set of keys (configurable via
maxmemory-samples, default 5). - From that sample, the key with the oldest
lru(least recently used) is evicted. - On subsequent evictions, Redis keeps a running minimum
lrufrom previous samples to decide which keys to include in the next sample.
Increasing maxmemory-samples (e.g., to 10) makes the algorithm more accurate but consumes more CPU. The default of 5 is usually sufficient.
Recommendations for Choosing a Policy
- Use
allkeys-lruwhen data has a clear hot/cold pattern—it maximizes the retention of frequently accessed keys. - Use
allkeys-randomif there's no obvious temperature difference (e.g., a cache that serves random data equally). - If some keys should never be evicted (keys without TTL), use
volatile-lruso that only expiring entries are candidates.
Memory Eviction Process and Impact
When maxmemory is set, Redis triggers eviction before every command that might allocate memory. If the server is in a state where used_memory > maxmemory and the policy is not noeviction, eviction runs frequently, hurting performance.
The cost of each eviction includes:
- Finding a candidate key (sampling).
- Deleting the key (freeing memory).
- Propagating the deletion to replicas (if replication is active).
Its strongly recommended to keep used_memory below maxmemory in production to avoid repeated eviction overhead.