Introduction

Redis provides powerful caching and data storage capabilities, but misconfigured key expiration, inefficient eviction policies, and excessive memory usage can degrade performance and lead to unpredictable behavior. Common pitfalls include failing to configure `maxmemory` properly leading to uncontrolled memory growth, using `volatile-ttl` eviction without setting TTLs leading to unpredictable deletions, using large blocking operations (`LRANGE`, `SORT`) causing latency spikes, mismanaging replication causing data inconsistencies, and not optimizing `save` and `appendfsync` settings causing persistence slowdowns. These issues become particularly problematic in high-throughput applications where Redis serves as a critical caching or database layer. This article explores Redis expiry, eviction, and performance bottlenecks, along with best practices for optimizing memory management and query efficiency.

Common Causes of High Latency and Data Inconsistencies in Redis

1. Inefficient Expiry Policies Causing Uncontrolled Memory Growth

Failing to set TTLs on keys can cause Redis to retain stale data indefinitely.

Problematic Scenario

SET user:123 "data"

Without a TTL, this key will remain in memory indefinitely.

Solution: Set TTLs on Cacheable Data

SET user:123 "data" EX 3600

Using `EX` ensures the key expires after 3600 seconds, preventing memory bloat.

2. Misconfigured Eviction Policies Causing Unpredictable Deletions

Using an eviction policy that does not align with application requirements can lead to critical data loss.

Problematic Scenario

maxmemory-policy allkeys-random

Redis evicts random keys, potentially removing critical session data.

Solution: Use `volatile-lru` or `volatile-ttl` for Cache-Only Keys

maxmemory-policy volatile-lru

Using `volatile-lru` ensures that only keys with TTLs are evicted first.

3. Large Blocking Commands Causing Latency Spikes

Executing expensive commands like `LRANGE` on large datasets can freeze Redis for extended periods.

Problematic Scenario

LRANGE mylist 0 -1

If `mylist` contains a large number of elements, this command will be slow.

Solution: Use Pagination for Large Lists

LRANGE mylist 0 100

Using smaller ranges limits the processing time per query.

4. Replication Lag Causing Data Inconsistencies

Heavy write loads can cause replicas to lag behind the primary Redis instance.

Problematic Scenario

slave-read-only no

Allowing writes on replicas can lead to inconsistency with the master.

Solution: Enable Read-Only Mode for Replicas

slave-read-only yes

Ensuring replicas are read-only prevents unintended modifications.

5. Inefficient Persistence Settings Slowing Down Writes

Improperly configured `appendfsync` settings can lead to slow write performance.

Problematic Scenario

appendonly yes
appendfsync always

Writing every command to disk immediately (`always`) can create high I/O overhead.

Solution: Use `appendfsync everysec` for Balanced Durability

appendonly yes
appendfsync everysec

Using `everysec` batches writes and improves performance without sacrificing durability.

Best Practices for Optimizing Redis Performance

1. Set Expiry for Cacheable Keys

Ensure that cache entries expire when no longer needed.

Example:

SET user:123 "data" EX 3600

2. Use the Right Eviction Policy

Align `maxmemory-policy` with application needs.

Example:

maxmemory-policy volatile-lru

3. Optimize Large Data Queries

Use pagination for large lists to avoid blocking the server.

Example:

LRANGE mylist 0 100

4. Prevent Replication Lag

Ensure replicas remain consistent with the master.

Example:

slave-read-only yes

5. Optimize Persistence Settings

Balance durability and performance in write-heavy workloads.

Example:

appendfsync everysec

Conclusion

High latency and inconsistent data in Redis often result from inefficient key expiry, improper eviction policies, blocking queries, replication lag, and poorly optimized persistence settings. By setting appropriate TTLs, configuring `maxmemory-policy` correctly, using paginated queries, ensuring replication consistency, and balancing persistence settings, developers can significantly improve Redis performance and reliability. Regular monitoring using `INFO`, `latency doctor`, and `redis-cli --bigkeys` helps detect and resolve performance issues before they impact production environments.