Back to Blog
Lesson 13 of the System Design: System Design Fundamentals course
ArchitectureJuly 30, 20263 min read

Mastering Cache Eviction Policies: LRU vs. LFU in Redis

Learn how to manage cache memory effectively using eviction policies. Compare LRU and LFU, configure Redis settings, and optimize your system's performance.

architecturerediscachingmemory-managementsystem-design
A detailed view of a metallic key with 'Vale' engraved on it, hanging against a blurred background.

Previously in this course, we covered Redis for Application Caching, where we learned to set and get values with basic TTLs. While TTLs help keep data fresh, they don't solve the problem of what happens when your cache hits its hard memory limit—that is where eviction policies come in.

Understanding Eviction from First Principles

Cache memory is finite. When you set a maxmemory limit on a system like Redis, you inevitably encounter a state where the cache is full, but the application needs to store new, important data. Eviction is the process of programmatically choosing which existing data to discard to make room for new entries.

If you don't choose an eviction policy, your cache will eventually refuse new writes, leading to errors. The goal of an effective policy is to maximize the "cache hit ratio" by evicting items that are least likely to be needed again soon.

Comparing LRU and LFU Policies

The two most common strategies for cache management are Least Recently Used (LRU) and Least Frequently Used (LFU).

PolicyLogicBest For
LRUEvicts the item that hasn't been accessed for the longest time.Workloads with temporal locality (recent items remain relevant).
LFUEvicts the item with the lowest access count over time.Workloads where some items are "hot" indefinitely, regardless of age.

Why the choice matters

  • LRU (Least Recently Used): It assumes that if you accessed a key 5 minutes ago, you are more likely to access it again than a key you accessed 2 hours ago. It is generally the default because it's computationally efficient and works well for most web traffic patterns.
  • LFU (Least Frequently Used): It tracks how often a key is accessed. If you have a "static" asset that is accessed 1,000 times a day, LFU will keep it safe, while LRU might evict it if it hasn't been touched in the last hour.

Configuring Eviction in Redis

Redis provides several maxmemory-policy settings that you can configure in redis.conf or via the CONFIG SET command.

To view your current policy:

Bash
redis-cli CONFIG GET maxmemory-policy

To change it to allkeys-lru (the industry standard for general caching):

Bash
redis-cli CONFIG SET maxmemory-policy allkeys-lru

Common Policies Explained:

  1. noeviction: (Default) Returns errors when memory limit is reached. Use this if you absolutely cannot afford to lose cache data.
  2. allkeys-lru: Evicts the least recently used keys, regardless of their expiration.
  3. volatile-lru: Evicts the least recently used keys, but only among those with an expiration set.
  4. allkeys-lfu: Evicts the least frequently used keys from the entire dataset.

Hands-on Exercise: Simulating Eviction

  1. Set a tight limit: Connect to your local Redis and set a very small memory limit: CONFIG SET maxmemory 2mb
  2. Set the policy: CONFIG SET maxmemory-policy allkeys-lru
  3. Fill the cache: Write a small script (or use redis-cli) to insert 100 small keys.
  4. Observe: Insert a 101st key. Check if the "oldest" key has been evicted using EXISTS key_1.

Common Pitfalls

  • Setting maxmemory too low: If your limit is too small, you trigger "cache thrashing," where the system spends more time evicting and re-fetching data than serving it.
  • Choosing the wrong policy for your data: If you use volatile-lru but your keys don't have TTLs, the cache will still fill up and return errors because there are no "volatile" keys to evict.
  • Ignoring maxmemory-samples: Redis uses a probabilistic approximation for LRU/LFU to save CPU. If you need perfect accuracy, you can increase maxmemory-samples in your configuration, but be aware this increases CPU usage.

Recap

Memory management is the backbone of a stable cache. By choosing allkeys-lru for most web applications, you ensure that frequently used data stays resident, while stale data is cleared automatically. Remember: your eviction policy is a trade-off between CPU overhead and cache accuracy.

Up next: We will discuss Measuring System Latency, where we define how to monitor if your cache configuration is actually providing the performance gains you expect.

Similar Posts