Redis uses eviction policies to manage memory when the maxmemory limit is reached. These policies determine which keys to remove to free up space for new data.
Eviction Policies
1. noeviction (default): When memory usage reaches maxmemory, Redis does not evict any existing data. Instead, it returns an error for write requests. This means the cache cannot accept new data once full.
2. volatile-lru: Evicts keys with an expiration set using the Least Recently Used (LRU) algorithm.
3. volatile-random: Randomly evicts keys that have an expiration time set.
4. volatile-ttl: Evicts keys with expiration times, selecting those with the earliest expiration first.
5. volatile-lfu: Evicts keys with expiration using the Least Frequently Used (LFU) algorithm.
6. allkeys-lru: Evicts any keys (including those without expiration) using the LRU algorithm.
7. allkeys-random: Randomly evicts any keys across the entire dataset.
8. allkeys-lfu: Evicts any keys using the LFU algorithm.
Policies volatile-lru, volatile-random, volatile-ttl, and volatile-lfu only consider keys that have an expiration time set. If no such keys exist, these policies behave like noeviction and return an error.
Policies allkeys-lru, allkeys-random, and allkeys-lfu consider all keys in the database, regardless of expiration settings.
LRU Algorithm
LRU (Least Recently Used) evicts data that hasn't been accessed for the longest time. A classic implementation uses a linked list: the most recently accessed item moves to the head, and eviction happens at the tail. However, moving items in a list is costly with many accesses, which can hurt performance.
Redis optimizes by using an aproximation of LRU. Each key has a timestamp of its last acces stored in the lru field of its redisObject structure. When eviction is needed, Redis randomly selects N keys (set via maxmemory-samples, default 5) and evicts the one with the oldest timestamp. This sample-based approach reduces overhead.
Example to set the sample size:
CONFIG SET maxmemory-samples 100
If eviction is triggered again, Redis selects new candidates that have an lru value smaller than the current smallest in the candidate set. Once the candidate set reaches maxmemory-samples, the key with the smallest lru is evicted.
Recommandations:
- Use
allkeys-lruwhen there is a clear distinction between hot (frequently accessed) and cold data. This keeps popular data in cache. - Use
allkeys-randomif access patterns are uniform without clear hot/cold data. - Use
volatile-lruif certain keys must be retained (e.g., pinned news or videos) by not setting their expiration, while allowing other expired keys to be evicted by LRU.
LFU Algorithm
LFU (Least Frequently Used) considers both access recency and frequency. Unlike LRU, LFU can quickly identify keys that were accessed only once but long ago. LFU first evicts keys with the lowest access frequency; if frequencies tie, it evicts the one with the oldest access time.
Redis implements LFU by splitting the 24-bit lru field into two parts: 16 bits for access timestamp (ldt) and 8 bits for a counter (counter) that tracks access frequency.
Getting and Setting Eviction Policies
-
Get current eviction policy:
127.0.0.1:6379> config get maxmemory-policyThis shows the current policy (e.g.,
noeviction). -
Get max memory limit:
127.0.0.1:6379> config get maxmemoryIf set to 0, no limit is imposed on 64-bit systems; on 32-bit systems, maximum memory is 3 GB due to system overhead.
-
Set eviction policy via config file (redis.conf):
maxmemory-policy allkeys-lruSet via command:
127.0.0.1:6379> config set maxmemory-policy allkeys-lru -
Set max memory limit:
127.0.0.1:6379> config set maxmemory 100mbThis sets the maximum memory usage to 100 MB.