Mastering Redis Cache Eviction: Strategies, Pitfalls, and Solutions

Explore Redis cache eviction policies, understand how strategies like allkeys‑lru, volatile‑ttl, and noeviction work, and learn practical solutions for cache penetration, breakdown, and avalanche—including Bloom filters, mutex locks, and staggered expirations—to keep your backend resilient under high load.

Architect's Guide
Architect's Guide
Architect's Guide
Mastering Redis Cache Eviction: Strategies, Pitfalls, and Solutions

Interview Question: How Does Redis Cache Eviction Work?

Eviction Strategies

noeviction: Returns an error when memory limit is reached and a client tries to execute a command that would use more memory (most write commands, except DEL and a few others).

allkeys-lru: Evicts the least recently used key to make space for new data.

volatile-lru: Evicts the least recently used key among keys with an expiration set.

allkeys-random: Evicts a random key to free space.

volatile-random: Evicts a random key among keys with an expiration set.

volatile-ttl: Evicts keys with an expiration, preferring those with the shortest TTL.

volatile-lfu: Evicts the least frequently used key among keys with an expiration.

allkeys-lfu: Evicts the least frequently used key among all keys.

If no keys satisfy the eviction criteria, the volatile-lru , volatile-random , and volatile-ttl strategies behave similarly to noeviction .

Choosing the right eviction policy is crucial and depends on your application's access pattern; you can adjust the policy at runtime and monitor hit/miss rates via the Redis INFO command for tuning.

General guidelines:

Use allkeys-lru when your request distribution follows a power‑law, meaning a subset of elements is accessed far more frequently; a safe default if unsure.

Use allkeys-random for uniformly distributed access or cyclic scans.

Use volatile-ttl when you want the TTL set at object creation to decide expiration.

allkeys-lru and volatile-random are useful when a single instance handles caching and persistence of some keys, though running two instances is often a better solution.

Setting expiration on keys also consumes memory, so allkeys-lru can be more efficient because it avoids the overhead of storing expiration metadata under memory pressure.

How the Eviction Process Works

Understanding the eviction workflow is essential:

A client issues a new command that adds data.

Redis checks memory usage; if it exceeds maxmemory , it applies the configured eviction policy.

Another command is executed, and the cycle repeats.

The system continuously pushes memory usage beyond the limit and then evicts keys to bring usage back below the threshold.

If a command generates a large amount of data (e.g., storing the result of a massive set intersection), the memory limit can be quickly exceeded.

Interview Question: Solutions for Cache Penetration, Breakdown, Avalanche, and Warm‑up?

Cache Penetration

Cache penetration occurs when queries request data that does not exist; because the cache does not write on miss and the backend also returns nothing, each request hits the database, potentially overwhelming it under high traffic.

Solution

Common approaches include using a Bloom filter to block requests for non‑existent keys, or caching empty results with a very short TTL (no more than five minutes).

Cache Breakdown (Cache Stampede)

When a cached key expires and many concurrent requests simultaneously try to fetch the data from the database, the backend can be overloaded.

Solution

Use locking or queuing to ensure only one request repopulates the cache. A simple technique is to add a random offset (e.g., 1–5 minutes) to the expiration time so that keys do not expire all at once.

Cache Avalanche

Cache avalanche happens when many keys share the same expiration time and expire together, causing a sudden surge of database traffic.

Solution

1. Use a mutex key (e.g., Redis SETNX) to ensure only one process loads data from the database. 2. “Pre‑emptive” mutex: set a short internal timeout (timeout1) smaller than the actual cache timeout (timeout2); when timeout1 expires, extend it and reload the cache. 3. “Never expire”: store the logical expiration inside the value and refresh the cache asynchronously, keeping the physical key without an expiration.

Summary

Penetration: cache miss, DB miss, high concurrency, few keys.

Breakdown: cache miss, DB hit, high concurrency, few keys.

Avalanche: cache miss, DB hit, high concurrency, many keys.

Although terminology differs, all scenarios can be mitigated with rate‑limiting mutexes to protect database stability.

图片
图片
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendPerformanceRediscache penetrationCache Eviction
Architect's Guide
Written by

Architect's Guide

Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.