Distributed Caching with Redis: Cache-Aside, TTL, Cache Stampede, Hot Keys & Redis Cluster

Distributed Caching with Redis: Cache-Aside, TTL, Cache Stampede, Hot Keys & Redis Cluster

Distributed Caching with Redis

Caching becomes useful when data is read frequently but changes relatively infrequently.

The goal is simple:

  • reduce database calls
  • improve application latency
  • protect downstream systems from heavy read traffic

For high-traffic applications, repeatedly querying the database for the same information is expensive. A caching layer allows frequently accessed data to be served much faster.

Types of Caching

There are several caching approaches commonly used in modern applications.

1. Application / Local Cache

The cache exists inside the application process or JVM.

Typical technologies include:

  • ConcurrentHashMap
  • Caffeine
  • Ehcache

Local caching is extremely fast because there is no network call between the application and cache.

However, every application instance has its own copy of the cache.

2. Distributed Cache

A distributed cache is shared across multiple application instances.

Examples include:

  • Redis
  • Apache Ignite
  • Memcached

This is especially useful when your application runs as multiple pods, containers, or servers and they all need access to the same cached state.

3. Database Cache

Databases also cache frequently accessed pages and data internally.

This improves database performance without requiring the application to manage everything directly.

4. CDN Cache

CDNs are mainly useful for geographically distributed static or content-oriented data.

Common examples:

  • CloudFront
  • Cloudflare
  • Akamai

Typical cached content includes:

  • images
  • CSS
  • JavaScript
  • videos

Basic Redis Architecture

The basic architecture diagram in your source shows the application checking Redis first and going to the database only on a cache miss.

Common Caching Patterns

Four important caching patterns are:

  • Cache-Aside
  • Read-Through
  • Write-Through
  • Write-Behind / Write-Back

Let us understand them one by one.

Cache-Aside Pattern

Cache-aside, also called lazy loading, is one of the most commonly used application caching patterns.

The flow is:

Advantage

Only frequently accessed data enters the cache.

Disadvantage

The first request after a cache miss is slower because the application must fetch the data from the database.

What Happens When Cached Data Is Updated?

Consider this scenario:

Product price = ₹1000
Redis contains = ₹1000

Now the application updates the database:

Database = ₹1200

But Redis still contains:

Redis = ₹1000

Users may now receive stale data from the cache.

This is one of the most important caching problems to understand:

cache invalidation.

Recommended Cache Update Pattern

A simple and widely used pattern is:

1. Update Database
2. Delete / Invalidate Cache Entry


This approach keeps the database as the source of truth.

After the database transaction commits successfully, the relevant cache entry is invalidated.

Why Not Update Database and Redis Together?

A natural question is:

Why not update both Redis and the database at the same time?

Because this creates a dual-write consistency problem.

Imagine:

Database update succeeds
Redis update fails

or:

Redis update succeeds
Database update fails

Now the two systems contain different values.

A simpler pattern is:

Database remains the source of truth.

Then:

After the database commits successfully → invalidate the cache.

Read-Through Cache

In cache-aside:

Application → Cache → Database

The application itself handles the cache miss.

In a read-through cache, the cache layer is responsible for loading the value from the database.

Write-Through Cache

With write-through caching, the write is not considered complete until both the cache and database have been updated.

Conceptually:

Update Product
      ↓
Redis
      ↓
Database
      ↓
Success

The advantage is that the cache remains fresh.

The disadvantage is that writes become slower because both systems participate synchronously.

Write-Behind / Write-Back Cache

Write-behind caching optimizes write latency.

This can make writes very fast.

However, imagine:

Redis accepts write
      ↓
Server crashes
      ↓
Database was not updated

This can potentially lead to data loss.

Therefore, this pattern may be inappropriate for critical data such as:

  • payment state
  • account balance

It may be more suitable for workloads such as:

  • analytics counters
  • metrics
  • non-critical aggregation

Caching Pattern Comparison

PatternRead/Write BehaviorTypical Use
Cache-AsideApplication manages cacheMost application caching
Read-ThroughCache loads dataManaged caching abstraction
Write-ThroughCache + DB updated synchronouslyFresh cache
Write-BehindDB updated asynchronouslyHigh write throughput

TTL — Time To Live

Every cache entry should normally have an expiration strategy. It determines how long a cached value remains valid.

Manual cache invalidation is not always perfect, so TTL gives the system another mechanism for removing stale entries after a configured period.

How Do We Choose TTL?

TTL should not be selected randomly.

It should be based on business requirements.

Examples from the source:

Country list        → 24 hours
Product catalog     → 10–30 minutes
User profile        → 5 minutes
Stock availability  → seconds
Payment status      → generally avoid aggressive caching

The important principle is:

The more frequently the underlying data changes, the shorter the TTL generally needs to be.

Cache Stampede

Now imagine a very popular cache key:

product:iphone

receives:

20,000 requests/second

and suddenly the TTL expires.

All of those requests may experience a cache miss at roughly the same time and hit the database together.

This is called a cache stampede.

Instead of Redis protecting the database, the database suddenly receives a huge traffic spike.

How to Prevent Cache Stampede

The source highlights several common strategies:

  • TTL jitter
  • stale-while-revalidate
  • proactive refresh
  • request coalescing

Another frequently discussed approach in the FAQ is distributed locking.

TTL Jitter

TTL jitter prevents many cache entries from expiring simultaneously.

Suppose you cache:

100,000 products

with exactly:

TTL = 10 minutes

If they were loaded around the same time, many could expire together.

Instead, add some randomness:

TTL = 10 minutes + random(0–2 minutes)

Possible expirations:

10m 12s
10m 43s
11m 02s
11m 51s

The expirations are now distributed over time.

This reduces large traffic spikes caused by synchronized expiry

The Hot Key Problem

A hot key occurs when extremely high traffic targets the same Redis key or shard.

For example:

product:iphone16

may receive an unusually large number of requests.

Even if Redis is clustered, all requests for that key may still concentrate on the shard that owns the key.

That shard can become overloaded while other shards remain relatively underused.

How Can We Handle Hot Keys?

The source proposes several approaches:

  • local in-memory cache
  • key replication
  • CloudFront/CDN where suitable

For very frequently requested values, adding a small local cache can reduce the number of calls reaching Redis.

For content suitable for edge caching, a CDN can also absorb large amounts of traffic before it reaches the application or Redis layer.

Redis Cluster

Suppose one Redis server can store:

100 GB

but the application needs:

500 GB

A single Redis instance is no longer enough.

Redis Cluster allows data to be distributed across multiple shards.

For example:

Redis Cluster

Shard 1 → Product range A
Shard 2 → Product range B
Shard 3 → Product range C

Each shard can also have replicas for availability.

Redis Cluster provides:

  • sharding
  • replication
  • failover
  • horizontal scaling

Redis Sentinel vs Redis Cluster

This is a common interview question.

Redis Sentinel

Sentinel primarily provides:

  • monitoring
  • failover
  • primary discovery

If the primary Redis instance fails, Sentinel can help promote a replica to primary.

Redis Cluster

Redis Cluster provides:

  • sharding
  • replication
  • failover
  • horizontal scaling

A simple way to remember the distinction:

Sentinel → availability/failover for a non-sharded Redis deployment

Redis Cluster → partitioning + scaling + availability

Do We Need Redis Sentinel and Redis Cluster Together?

The source’s answer is:

No.

Redis Cluster already provides capabilities such as:

  • node monitoring
  • failure detection
  • replica promotion
  • shard management

Final Production Distributed Caching Architecture

he final architecture in your document combines several layers:

Users / Clients
      ↓
CloudFront / CDN
      ↓
AWS ALB
      ↓
Spring Boot Application Cluster
      ↓
Local Cache
      ↓ miss
Amazon ElastiCache for Redis Cluster
      ↓ miss
Amazon Aurora / RDS

For write/update operations:

Application
    ↓
Database
    ↓ successful commit
Invalidate / Update Cache

Frequently Asked Interview Questions

1. Is Redis the source of truth?

Normally:

No.

The database remains the durable source of truth.


2. What caching pattern would you choose for a product catalog?

Usually:

Cache-aside.

The application first checks Redis.

On cache miss, it reads the database and repopulates the cache.


3. On update, would you update Redis or delete the key?

A common approach is:

1. Update DB
2. Commit successfully
3. Invalidate Redis key

This reduces dual-write consistency problems.


4. What is cache stampede?

A cache stampede occurs when many requests simultaneously miss an expired cache entry and overwhelm the database.


5. How do you prevent cache stampede?

Common techniques include:

  • distributed locking
  • TTL jitter
  • stale-while-revalidate
  • proactive cache refresh

6. Redis Cluster vs Database Read Replicas?

These solve different problems.

Redis Cluster

Distributes Redis data/keys across shards.

Database Read Replica

Contains replicated database data and primarily improves read scalability.


7. Can Redis guarantee no data loss?

It depends on persistence and replication configuration.

But in a normal caching architecture, Redis should not be treated as the only durable store for critical business data.


8. When Shouldn’t You Cache?

Examples include:

  • rapidly changing balances
  • critical payment state
  • highly personalized sensitive data without careful cache-key/security design
  • rarely accessed information

Key Takeaways

The most important concepts to remember are:

  1. Database remains the source of truth.
  2. Redis reduces repeated database reads.
  3. Cache-aside is one of the most common caching patterns.
  4. After DB updates, cache invalidation is critical.
  5. TTL should be based on business freshness requirements.
  6. Cache stampede can overload the database when popular keys expire.
  7. TTL jitter helps spread expiration times.
  8. Hot keys can overload an individual Redis shard.
  9. Redis Cluster provides sharding and horizontal scaling.
  10. Sentinel focuses primarily on monitoring and failover.
  11. Local cache + distributed cache can be combined for extremely hot data.
  12. CDN caching should be used where the data/content model allows it.