Nextgen Blog
HomeLearnAIQuantumRoboticsSecuritySpaceAbout
Nextgen Blog

By Anubhav — full stack engineer, IIT Mandi CSE. Deep dives into AI, software engineering, and the technologies shaping the next generation of tech.

Navigate

  • Home
  • Learn
  • Blog
  • Archive
  • About

Topics

  • Artificial Intelligence
  • Quantum Computing
  • Robotics
  • Cybersecurity
  • Space Tech

Connect

Built with ❤️ & By - Anubhav

© 2026 Nextgen Blog by Anubhav. All rights reserved.

Privacy PolicyTerms of Service
Phase 03 · Partitioning, Replication & CachingChapter 18 of 33
17.
Phase 03Read time ~25 minDifficulty advanced

Advanced Caching

In this chapter
  • 01Introduction
  • 02Redis as a Distributed Cache
  • 03Redis Data Structures
  • 04Redis Strings
  • 05Redis Hashes
  • 06Redis Sets
  • 07Redis Sorted Sets
  • 08Redis Lists
  • 09Redis Streams
  • 10Redis Expiration
  • 11Redis Persistence vs Cache Mode
  • 12Redis Cluster Concept
  • 13Cache Partitioning
  • 14Hash Slot Concept
  • 15Why Partitioning Helps
  • 16Cache Replication
  • 17Cache Cluster Failure
  • 18Cache Failover
  • 19Cache Failover Is Not Free
  • 20Cache Replication vs Database Replication
  • 21Distributed Locks
  • 22Locking for Cache Stampede Protection
  • 23Distributed Lock Requirements
  • 24Lock Expiration
  • 25Fencing Tokens
  • 26Request Coalescing
  • 27Request Coalescing Flow
  • 28Stale-While-Revalidate
  • 29Stale-While-Revalidate Timeline
  • 30Refresh-Ahead
  • 31TTL Jitter
  • 32Probabilistic Early Refresh
  • 33Hot-Key Mitigation
  • 34Local L1 caching
  • 35Key replication
  • 36CDN caching
  • 37Request coalescing
  • 38Hot-Key Trade-Off
  • 39Multi-Region Caching
  • 40Multi-Region Cache Consistency
  • 41Regional Cache Failure
  • 42Cache Warming at Scale
  • 43Cache Warming Risks
  • 44Cache Observability
  • 45Hit ratio
  • 46Miss ratio
  • 47Latency
  • 48Evictions
  • 49Memory
  • 50Hot keys
  • 51Errors
  • 52Cache Latency Percentiles
  • 53Cache Capacity Monitoring
  • 54Eviction Policy Selection
  • 55Cache Security in Distributed Systems
  • 56Redis for Sessions
  • 57Redis for Distributed Counters
  • 58Redis for Rate Limiting
  • 59Cache vs Database
  • 60Cache vs Message Queue
  • 61Cache vs CDN
  • 62Advanced Cache Architecture
  • 63Cache Failure Strategy
  • 64Cache is slow
  • 65Cache is unavailable
  • 66Cache is empty
  • 67Cache is stale
  • 68Cache Timeouts
  • 69Cache Circuit Breaker
  • 70Graceful Degradation
  • 71Cache Consistency Strategy
  • 72Production Design Example
  • 73Advanced Production Checklist
  • 74Data
  • 75Freshness
  • 76Capacity
  • 77Distribution
  • 78Availability
  • 79Protection
  • 80Observability
  • 81Security
  • 82Interview Problem: Design a Cache for 1 Million RPS
  • 83Interview Problem: Cache Failure
  • 84Interview Problem: Hot Key
  • 85Interview Problem: Cache Stampede
  • 86Common Mistakes
  • 87Mistake 1: Treating Redis as automatically highly available
  • 88Mistake 2: Assuming cache failure is harmless
  • 89Mistake 3: Ignoring hot keys
  • 90Mistake 4: Using distributed locks casually
  • 91Mistake 5: No timeout on cache calls
  • 92Mistake 6: Ignoring serialization overhead
  • 93Mistake 7: Refreshing everything simultaneously
  • 94Mistake 8: Treating cache replication as database durability
  • 95Mistake 9: Ignoring regional consistency
  • 96Mistake 10: Caching sensitive data without isolation
  • 97Practical Project — Production-Style Redis Cache
  • 98GET
  • 99PUT
  • 100Testing the Cache
  • 101Normal hit
  • 102Miss
  • 103Expiration
  • 104Stampede
  • 105Redis failure
  • 106Database failure
  • 107Master Mental Model
  • 108Chapter Summary
  • 109Final Interview Checklist
  • 110What's Next?
  • 111Chapter 17 — Storage Systems
In this chapter (111 sections)
01Introduction02Redis as a Distributed Cache03Redis Data Structures04Redis Strings05Redis Hashes06Redis Sets07Redis Sorted Sets08Redis Lists09Redis Streams10Redis Expiration11Redis Persistence vs Cache Mode12Redis Cluster Concept13Cache Partitioning14Hash Slot Concept15Why Partitioning Helps16Cache Replication17Cache Cluster Failure18Cache Failover19Cache Failover Is Not Free20Cache Replication vs Database Replication21Distributed Locks22Locking for Cache Stampede Protection23Distributed Lock Requirements24Lock Expiration25Fencing Tokens26Request Coalescing27Request Coalescing Flow28Stale-While-Revalidate29Stale-While-Revalidate Timeline30Refresh-Ahead31TTL Jitter32Probabilistic Early Refresh33Hot-Key Mitigation34Local L1 caching35Key replication36CDN caching37Request coalescing38Hot-Key Trade-Off39Multi-Region Caching40Multi-Region Cache Consistency41Regional Cache Failure42Cache Warming at Scale43Cache Warming Risks44Cache Observability45Hit ratio46Miss ratio47Latency48Evictions49Memory50Hot keys51Errors52Cache Latency Percentiles53Cache Capacity Monitoring54Eviction Policy Selection55Cache Security in Distributed Systems56Redis for Sessions57Redis for Distributed Counters58Redis for Rate Limiting59Cache vs Database60Cache vs Message Queue61Cache vs CDN62Advanced Cache Architecture63Cache Failure Strategy64Cache is slow65Cache is unavailable66Cache is empty67Cache is stale68Cache Timeouts69Cache Circuit Breaker70Graceful Degradation71Cache Consistency Strategy72Production Design Example73Advanced Production Checklist74Data75Freshness76Capacity77Distribution78Availability79Protection80Observability81Security82Interview Problem: Design a Cache for 1 Million RPS83Interview Problem: Cache Failure84Interview Problem: Hot Key85Interview Problem: Cache Stampede86Common Mistakes87Mistake 1: Treating Redis as automatically highly available88Mistake 2: Assuming cache failure is harmless89Mistake 3: Ignoring hot keys90Mistake 4: Using distributed locks casually91Mistake 5: No timeout on cache calls92Mistake 6: Ignoring serialization overhead93Mistake 7: Refreshing everything simultaneously94Mistake 8: Treating cache replication as database durability95Mistake 9: Ignoring regional consistency96Mistake 10: Caching sensitive data without isolation97Practical Project — Production-Style Redis Cache98GET99PUT100Testing the Cache101Normal hit102Miss103Expiration104Stampede105Redis failure106Database failure107Master Mental Model108Chapter Summary109Final Interview Checklist110What's Next?111Chapter 17 — Storage Systems

1. Introduction#

Chapter 15 introduced the fundamentals of caching:

  • cache hit and miss
  • cache-aside
  • TTL
  • invalidation
  • LRU/LFU
  • local vs distributed cache
  • cache stampede
  • hot keys
  • cache warming

Now we move to production-grade caching.

At large scale, the cache itself becomes a distributed system.

A typical architecture may look like:

                         Users
                           |
                           v
                    Load Balancer
                           |
                           v
                    Application Tier
                    /              \
                   /                \
          Local Cache              Redis
              |                     |
              |                     v
              |               Cache Cluster
              |                     |
              +----------+----------+
                         |
                         v
                      Database

At this level we need to think about:

  • partitioning
  • replication
  • failover
  • distributed locks
  • hot keys
  • cache consistency
  • multi-region operation
  • observability
  • memory management
  • operational recovery

The central idea is:

A cache is not merely a faster key-value store. At scale, it is a distributed infrastructure component with its own availability, consistency, capacity, and failure requirements.


2. Redis as a Distributed Cache#

Redis is commonly used as a fast in-memory data store.

Conceptually:

Application
     |
     v
   Redis
     |
     v
   Memory

Redis can support many use cases beyond simple caching, including:

  • caching
  • sessions
  • counters
  • rate limiting
  • queues in some designs
  • distributed coordination primitives
  • pub/sub
  • temporary state

For system design, do not think of Redis only as:

"A cache."

Think of it as:

A high-speed data structure server that can be used as a cache and for several coordination/state workloads.


3. Redis Data Structures#

Redis supports multiple data structures.

Common ones include:

String
Hash
List
Set
Sorted Set
Stream

The choice depends on the data model.


4. Redis Strings#

A string stores a value associated with a key.

Example:

user:123:name -> "Anubhav"

Or:

product:123 -> "{...json...}"

Common use cases:

  • cached objects
  • counters
  • tokens
  • flags
  • serialized JSON

Conceptually:

SET user:123 "Anubhav"
GET user:123

5. Redis Hashes#

A hash stores fields under a key.

Example:

user:123
    name = Anubhav
    city = Delhi
    role = engineer

Conceptually:

user:123
    |
    +-- name
    +-- city
    +-- role

Useful when accessing individual fields rather than replacing the entire object.


6. Redis Sets#

A set stores unique values.

Example:

online-users
    |
    +-- user:101
    +-- user:102
    +-- user:103

Useful for:

  • membership
  • deduplication
  • tags
  • unique relationships

7. Redis Sorted Sets#

A sorted set associates values with scores.

Example:

leaderboard
 
Anubhav -> 9800
Rahul   -> 9500
Amit    -> 9100

This is useful for:

  • leaderboards
  • ranking
  • priority-like workloads
  • time-based scoring

8. Redis Lists#

Lists provide ordered collections.

Conceptually:

queue
 |
 +-- task A
 +-- task B
 +-- task C

They can be useful for certain queue/work-list patterns.

For production messaging, however, the correct choice depends on delivery guarantees and workload requirements.


9. Redis Streams#

Streams provide an append-oriented data structure with consumer-oriented processing features.

Conceptually:

Event Stream
    |
    +-- Event 1
    +-- Event 2
    +-- Event 3

They can be used for:

  • event processing
  • activity feeds
  • asynchronous workflows
  • consumer groups

Redis Streams are different from simply storing cached values.


10. Redis Expiration#

A cache entry can have an expiration time.

Conceptually:

product:123
TTL = 300 seconds

After expiration, the key becomes eligible to disappear according to Redis's expiration behavior.

Expiration is important for:

  • sessions
  • temporary tokens
  • cached API responses
  • temporary locks
  • short-lived state

11. Redis Persistence vs Cache Mode#

Redis can be used purely as an ephemeral cache, but Redis deployments can also use persistence mechanisms.

This creates an important distinction:

Pure Cache
 
Redis
  |
  X restart
  |
Data can disappear

versus:

Redis with persistence
 
Redis
  |
  v
Persistence
  |
  v
Recovery

If Redis is being used as a cache, losing its contents may be acceptable if the database can repopulate it.

If Redis stores important application state, durability requirements become much more important.

Never assume:

"Redis means data is always temporary."

The architecture determines whether Redis data is disposable.


12. Redis Cluster Concept#

A large cache may need more memory and throughput than one machine can provide.

Instead of:

One Redis

we can use:

Redis Cluster
   |
   +-- Node A
   +-- Node B
   +-- Node C
   +-- Node D

The key idea is:

Distribute keys across multiple nodes.

This is cache partitioning.


13. Cache Partitioning#

Suppose we have:

1 billion keys

A single node may not have enough memory.

We can partition keys:

              Key Space
                  |
        +---------+---------+
        |         |         |
        v         v         v
      Node A    Node B    Node C

For example:

user:1   -> Node A
user:2   -> Node C
user:3   -> Node B

The routing mechanism determines where each key belongs.


14. Hash Slot Concept#

Many distributed cache systems use a deterministic partitioning mechanism.

A simplified model:

slot = hash(key) % N

Then:

slot -> cache node

The actual implementation can use a more sophisticated fixed slot space.

The important system-design concept is:

Key
 |
 v
Hash / Partition Function
 |
 v
Partition
 |
 v
Cache Node

15. Why Partitioning Helps#

Suppose one cache server provides:

100 GB memory

and we need:

1 TB

We can distribute data:

Node 1 -> 100 GB
Node 2 -> 100 GB
Node 3 -> 100 GB
...

Partitioning allows the cache to scale horizontally.


16. Cache Replication#

Partitioning improves capacity.

Replication improves availability.

A common architecture is:

Partition 1
   |
   +-- Primary
   +-- Replica
 
Partition 2
   |
   +-- Primary
   +-- Replica
 
Partition 3
   |
   +-- Primary
   +-- Replica

Now we have:

Partitioning -> scale
Replication  -> redundancy

These solve different problems.


17. Cache Cluster Failure#

Suppose:

Partition A Primary
       X

A replica may be promoted.

Partition A Replica
        |
        v
New Primary

Applications need to continue routing requests to the correct partition.

This requires cluster-aware routing and failure detection.


18. Cache Failover#

A simplified failover process:

1. Detect primary failure
2. Determine whether failure is real
3. Promote replica
4. Update cluster metadata
5. Redirect traffic
6. Reconnect clients
7. Rebuild/repair redundancy

The actual implementation depends on the cache technology.


19. Cache Failover Is Not Free#

Suppose a cache node fails.

If cached data is disposable:

Cache failure
    |
    v
Database fallback

But if millions of requests miss simultaneously:

Cache failure
    |
    v
Millions of misses
    |
    v
Database overload

Therefore:

Cache failure can become a database failure if fallback traffic is uncontrolled.


20. Cache Replication vs Database Replication#

Do not confuse:

Database replication

with:

Cache replication

Database replication protects persistent data.

Cache replication primarily protects cached state and availability.

Example:

Database
   |
   +-- DB Replica 1
   +-- DB Replica 2
 
Cache
   |
   +-- Cache Replica 1
   +-- Cache Replica 2

The requirements are different.


21. Distributed Locks#

Sometimes many application instances need to coordinate around one operation.

Example:

100 servers
     |
     v
same cache key expired

All servers may attempt to regenerate it.

A distributed lock can ensure:

Server A -> gets lock
Server B -> waits
Server C -> waits

Then:

Server A
   |
   v
Database
   |
   v
Cache
   |
   v
Release lock

22. Locking for Cache Stampede Protection#

Suppose:

product:123

expires.

Without coordination:

Request 1 -> DB
Request 2 -> DB
Request 3 -> DB
...
Request 10,000 -> DB

With a lock:

Request 1
   |
 gets lock
   |
   v
Database
   |
   v
Cache
 
Requests 2-10,000
   |
 wait/retry
   |
   v
Cache HIT

This can protect the database.


23. Distributed Lock Requirements#

A distributed lock should consider:

  • ownership
  • expiration
  • release
  • process crashes
  • network partitions
  • clock assumptions
  • lock renewal
  • fencing where appropriate

A simple lock implementation is not automatically safe for every distributed workflow.


24. Lock Expiration#

Suppose:

Server A
gets lock

Then Server A crashes.

Without expiration:

Lock remains forever

The system can become stuck.

Therefore locks commonly have a bounded lifetime.

But expiration creates another problem.

Suppose:

Lock TTL = 5 sec
Operation = 10 sec

The lock may expire while Server A is still working.

Then:

Server B
gets same lock

Now both may believe they own the operation.

This is why distributed locking requires careful design.


25. Fencing Tokens#

A stronger approach is to assign monotonically increasing fencing tokens.

Example:

Server A -> token 41
Server B -> token 42

The protected resource can reject stale operations:

token 41 -> reject
token 42 -> accept

This prevents an old lock holder from continuing to modify the protected resource after a newer owner has taken over.

Fencing is particularly important when operations can outlive lock leases.


26. Request Coalescing#

Request coalescing means combining multiple simultaneous requests for the same missing value into one backend operation.

Example:

100 requests
      |
      v
Same cache key
      |
      v
One database query
      |
      v
Result shared

This is different from simply having a cache.

It specifically protects against concurrent misses.


27. Request Coalescing Flow#

Request A ----\
Request B -----\
Request C ------> Loader
Request D -----/    |
Request E ----/     v
                  Database
                     |
                     v
                   Cache
                     |
          +----------+----------+
          |          |          |
          v          v          v
          A          B          C

This is one of the most effective ways to reduce stampedes for very hot keys.


28. Stale-While-Revalidate#

A powerful strategy is:

Serve stale data immediately while refreshing it in the background.

Example:

Cache entry:
Fresh for 60 sec
Stale-but-servable for another 300 sec

When stale:

Request
   |
   v
Cache
   |
   +---- return stale value
   |
   +---- background refresh

This avoids making the user wait for the refresh.


29. Stale-While-Revalidate Timeline#

0s -------- 60s -------- 360s
|            |             |
Fresh        Stale         Expired
             but            |
             usable         |

During the stale period:

User -> stale response
       +
       background refresh

This is useful when:

  • availability is more important than perfect freshness
  • backend data is expensive to generate
  • users can tolerate small staleness

30. Refresh-Ahead#

Refresh-ahead means refreshing data before it expires.

Example:

TTL = 10 minutes
Refresh at = 9 minutes

Flow:

Cache
  |
  | approaching expiry
  v
Background refresh
  |
  v
Fresh value

The next user never experiences a cold miss.

This works particularly well for predictable popular keys.


31. TTL Jitter#

If millions of entries are inserted simultaneously with:

TTL = 300 seconds

they may all expire around the same time.

Instead:

TTL = 300 + random(0..60)

This spreads expiration times.

Conceptually:

Without jitter:
 
||||||||||||||||||
same expiration
 
With jitter:
 
| |  ||   | | || |  |
spread expiration

TTL jitter reduces synchronized cache misses.


32. Probabilistic Early Refresh#

Another advanced technique is to refresh entries probabilistically as they approach expiration.

Instead of:

At exact expiration -> refresh

the system can gradually increase the probability of refreshing earlier.

This spreads backend work over time.

The exact algorithm depends on the implementation.

The goal is:

Avoid synchronized regeneration of popular values.


33. Hot-Key Mitigation#

Suppose:

product:123

receives:

500,000 requests/sec

One cache node or one logical key can become hot.

Strategies:

1. Local L1 caching#

App memory
    |
    v
Redis

Hot values are served locally.

2. Key replication#

Store the same logical value under multiple physical cache keys.

product:123:replica1
product:123:replica2
product:123:replica3

Requests can be distributed.

3. CDN caching#

Move extremely popular public content closer to clients.

4. Request coalescing#

Reduce duplicate backend work.


34. Hot-Key Trade-Off#

Replicating a hot key reduces read concentration but increases:

  • memory usage
  • invalidation complexity
  • write/update work

For example:

One copy:
1 key
 
Ten replicas:
10 keys

When the value changes:

Update 10 copies

Therefore hot-key mitigation is a trade-off.


35. Multi-Region Caching#

Global applications may deploy caches near users.

                 Global Users
                 /     |     \
                v      v      v
             India    US    Europe
               |       |       |
               v       v       v
             Cache   Cache   Cache
               \       |       /
                \      |      /
                 v     v     v
                    Database

Benefits:

  • lower read latency
  • regional traffic isolation
  • improved user experience

Challenges:

  • consistency
  • invalidation propagation
  • regional failures
  • duplicate memory
  • cross-region network traffic

36. Multi-Region Cache Consistency#

Suppose:

India Cache:
price = 100
 
US Cache:
price = 100

A product price changes:

Database:
price = 120

Now:

India Cache -> 100
US Cache    -> 100

The system needs to invalidate or refresh both regions.

Possible approaches:

Database Update
      |
      v
Global Event
   /       \
  v         v
India     US
Cache     Cache
Invalidate

The propagation itself may be asynchronous.


37. Regional Cache Failure#

Suppose the India cache cluster fails.

Possible fallback:

India Users
     |
     v
India Cache
     X
     |
     v
Regional fallback
     |
     v
Database / alternate cache

But cross-region fallback increases latency.

Therefore a regional cache should ideally have enough redundancy to handle local failures.


38. Cache Warming at Scale#

After a cache cluster restart:

Cache = empty

Millions of requests may immediately cause misses.

A warming strategy may preload:

  • popular products
  • configuration
  • frequently accessed profiles
  • homepage content
  • recommendation results

Architecture:

Database
   |
   v
Warm-up Worker
   |
   v
Cache

The worker can prioritize the most valuable keys.


39. Cache Warming Risks#

Bad warming can be harmful.

Suppose you attempt to preload:

10 billion records

The database may become overloaded.

Therefore warming should consider:

  • popularity
  • traffic predictions
  • rate limits
  • batch size
  • database capacity
  • cache capacity

Warm the data that provides the most value.


40. Cache Observability#

A production cache needs monitoring.

Important metrics include:

Hit ratio#

hits / total requests

Miss ratio#

misses / total requests

Latency#

Measure:

  • p50
  • p95
  • p99

Evictions#

High eviction rates may indicate insufficient capacity or poor key/TTL strategy.

Memory#

Monitor:

used memory
max memory
fragmentation

Hot keys#

Identify disproportionately accessed keys.

Errors#

Track:

  • timeouts
  • connection failures
  • command failures
  • cluster errors

41. Cache Latency Percentiles#

Average latency can hide problems.

Example:

Average = 2 ms

But:

p50 = 1 ms
p95 = 4 ms
p99 = 80 ms

A small percentage of requests are very slow.

At large scale, p99 matters significantly.

Always monitor cache latency percentiles.


42. Cache Capacity Monitoring#

Suppose:

Max memory = 100 GB
Used = 98 GB

The cache is close to capacity.

Potential consequences:

  • increased eviction
  • lower hit ratio
  • higher database load

Therefore capacity should be monitored before the system reaches the limit.


43. Eviction Policy Selection#

Different workloads benefit from different policies.

Possible policies include:

  • LRU-like behavior
  • LFU-like behavior
  • TTL-based expiration
  • no-eviction behavior
  • workload-specific strategies

Questions to ask:

Are recent items more valuable?
Are frequent items more valuable?
Is data disposable?
What happens when memory is full?

The answer determines the appropriate policy.


44. Cache Security in Distributed Systems#

A distributed cache may contain:

sessions
tokens
personal data
authorization state
financial information

Security considerations include:

  • network encryption
  • authentication
  • authorization
  • access isolation
  • secret management
  • data minimization
  • safe key naming
  • avoiding accidental public exposure

Never expose an internal cache directly to untrusted clients.


45. Redis for Sessions#

Instead of storing sessions in one application server:

Server A
  |
  +-- Session

use shared session storage:

Server A \
Server B  ---> Redis
Server C /

Then any application server can retrieve the session.

This supports horizontal scaling.

Example:

session:abc123
    |
    +-- user_id
    +-- expires_at

46. Redis for Distributed Counters#

Suppose we need:

page views = 1,000,000

Multiple application servers update the same counter.

A distributed cache can provide atomic counter operations.

Conceptually:

Server A --\
Server B ---+--> Counter
Server C --/

This avoids storing every individual increment in the database.

The durability requirements must still be considered.


47. Redis for Rate Limiting#

Caching systems can also support rate limiting.

Example:

user:123:requests

Increment:

1
2
3
...
100

Policy:

100 requests / minute

If count exceeds the limit:

429 Too Many Requests

A more complete rate-limiting architecture will be covered later in the system-design course.


48. Cache vs Database#

A cache is usually optimized for:

  • speed
  • temporary data
  • repeated reads
  • low latency

A database is optimized for:

  • durable storage
  • transactions
  • complex queries
  • persistence
  • recovery

Therefore:

Cache != Database

Even if both can store key-value data.


49. Cache vs Message Queue#

A cache answers:

"What is the current value?"

A queue answers:

"What work/event needs to be processed?"

Example:

Cache:
user:123 -> profile
 
Queue:
send-email -> job123

They solve different problems.


50. Cache vs CDN#

A CDN primarily caches content close to users at the network edge.

An application cache usually caches application-level data.

Example:

Browser
  |
  v
CDN
  |
  v
Application
  |
  v
Redis
  |
  v
Database

All are caching layers, but they serve different purposes.


51. Advanced Cache Architecture#

A large production system might look like:

                         Users
                           |
                           v
                         CDN
                           |
                           v
                     Load Balancer
                           |
                           v
                  Application Servers
                  /               \
                 /                 \
          L1 Local Cache       L2 Redis Cluster
                                   |
                         +---------+---------+
                         |         |         |
                         v         v         v
                       Node A    Node B    Node C
                         |         |         |
                         +---------+---------+
                                   |
                                   v
                              DB Cluster

Different layers absorb different types of traffic.


52. Cache Failure Strategy#

A mature cache architecture should define what happens when:

Cache is slow#

Use:

  • timeouts
  • circuit breakers
  • fallback behavior

Cache is unavailable#

Use:

  • database fallback where safe
  • degraded responses
  • rate limiting
  • request coalescing

Cache is empty#

Use:

  • controlled warming
  • lazy population
  • stampede protection

Cache is stale#

Use:

  • TTL
  • invalidation
  • refresh
  • business-specific tolerance

53. Cache Timeouts#

Never allow cache calls to hang indefinitely.

Example:

Application
    |
    v
Redis
    |
   timeout

Without a timeout:

Request threads
      |
      v
waiting...
waiting...
waiting...

This can exhaust application resources.

A cache timeout should be aligned with the application's latency budget.


54. Cache Circuit Breaker#

Suppose Redis is failing.

Without protection:

Every request
    |
    v
Redis
    |
    X
failure

The application repeatedly waits for the failing dependency.

A circuit breaker can temporarily stop requests to the failing cache:

Redis failure
    |
    v
Circuit OPEN
    |
    v
Fast fallback

This can protect application resources.


55. Graceful Degradation#

Suppose recommendation cache fails.

Instead of:

Whole page = ERROR

the application can return:

Page
 |
 +-- Product information
 +-- Reviews
 +-- Purchase
 |
 +-- Recommendations unavailable

This is graceful degradation.

Caching often enables optional features to fail independently.


56. Cache Consistency Strategy#

For every cache, explicitly define:

Source of truth
Freshness requirement
Invalidation mechanism
Fallback behavior

Example:

Source of truth:
PostgreSQL
 
Freshness:
< 30 seconds
 
Invalidation:
TTL + event
 
Fallback:
Database
 
Failure:
Serve stale value if safe

This is much better than simply saying:

"We'll use Redis."


57. Production Design Example#

Suppose we are building an e-commerce product API.

Requirements:

Traffic = 300,000 reads/sec
Product data changes relatively infrequently
Product details can tolerate small staleness
High availability required

Possible design:

Client
  |
  v
CDN
  |
  v
Application
  |
  v
L1 Local Cache
  |
  v
Redis Cluster
  |
  v
Database Replicas

Flow:

1. CDN hit -> return
2. CDN miss -> application
3. L1 hit -> return
4. L1 miss -> Redis
5. Redis hit -> populate L1 -> return
6. Redis miss -> DB
7. DB result -> Redis -> L1 -> return

This creates a multi-level cache.


58. Advanced Production Checklist#

Before deploying a large cache, answer:

Data#

  • What is cached?
  • What is the source of truth?
  • What is the key format?
  • What is the average object size?

Freshness#

  • What is acceptable staleness?
  • What is the TTL?
  • How is invalidation handled?
  • Can stale data be served?

Capacity#

  • How much data?
  • How much memory?
  • What is the growth rate?
  • What is the expected hit ratio?

Distribution#

  • How are keys partitioned?
  • How are hot keys handled?
  • How is data rebalanced?

Availability#

  • What happens when a node fails?
  • Is replication enabled?
  • How does failover work?
  • Can the application survive cache loss?

Protection#

  • How are stampedes prevented?
  • Are timeouts configured?
  • Is circuit breaking configured?
  • Is database fallback safe?

Observability#

  • hit ratio
  • miss ratio
  • p50/p95/p99 latency
  • memory
  • evictions
  • hot keys
  • errors
  • connection count

Security#

  • authentication
  • authorization
  • encryption
  • sensitive-data handling
  • network isolation

59. Interview Problem: Design a Cache for 1 Million RPS#

Requirements:

1,000,000 requests/sec
Average object = 2 KB
Hit ratio target = 98%

Database fallback:

2% × 1,000,000
=
20,000 requests/sec

Approximate cache traffic:

980,000 requests/sec

Now ask:

Can one node handle this?
How much memory is required?
How many shards?
How many replicas?
What is the network bandwidth?
What happens during a node failure?

If average object size is 2 KB:

980,000 × 2 KB
≈ 1.96 GB/sec

of response payload traffic at the cache boundary under a simplified assumption.

This demonstrates why cache sizing requires both:

  • memory calculations
  • throughput calculations

60. Interview Problem: Cache Failure#

Question:

Redis suddenly becomes unavailable. What happens?

Bad answer:

"The application reads from the database."

A stronger answer considers:

Redis failure
    |
    +-- timeout quickly
    |
    +-- circuit breaker
    |
    +-- controlled DB fallback
    |
    +-- request coalescing
    |
    +-- rate limiting
    |
    +-- graceful degradation

Then ask:

Can the database handle the fallback load?

If not, the system needs protection.


61. Interview Problem: Hot Key#

Question:

One cache key receives 500,000 requests/sec. What do you do?

Possible reasoning:

1. Confirm it is a hot key.
2. Check whether data is public/cacheable.
3. Add local L1 caching.
4. Use request coalescing.
5. Replicate the key if needed.
6. Use CDN if appropriate.
7. Monitor invalidation cost.

Do not immediately add more random cache nodes.

If every request hashes to the same logical key, simply adding nodes may not solve the problem.


62. Interview Problem: Cache Stampede#

Question:

A popular key expires every five minutes and causes database overload.

Possible solution:

TTL
 +
TTL jitter
 +
request coalescing
 +
background refresh

For example:

At 4m30s:
background refresh
 
At 5m:
still fresh
 

or:

First request after expiry:
gets refresh lock
 
Other requests:
wait/share result

63. Common Mistakes#

Mistake 1: Treating Redis as automatically highly available#

Availability depends on the deployment architecture.

Mistake 2: Assuming cache failure is harmless#

A cache outage can overload the database.

Mistake 3: Ignoring hot keys#

One key can overload a node.

Mistake 4: Using distributed locks casually#

Incorrect lock semantics can cause duplicate or conflicting work.

Mistake 5: No timeout on cache calls#

Slow cache dependencies can consume application resources.

Mistake 6: Ignoring serialization overhead#

Large objects can be expensive even if the cache lookup itself is fast.

Mistake 7: Refreshing everything simultaneously#

This can cause cache stampedes.

Mistake 8: Treating cache replication as database durability#

They solve different problems.

Mistake 9: Ignoring regional consistency#

Multi-region caches can return different values temporarily.

Mistake 10: Caching sensitive data without isolation#

This can create severe security issues.


64. Practical Project — Production-Style Redis Cache#

Build an API:

GET    /products/:id
POST   /products
PUT    /products/:id
DELETE /products/:id

Architecture:

Client
  |
  v
API
  |
  +---- L1 Local Cache
  |
  +---- Redis
  |
  +---- PostgreSQL

Implement:

GET#

L1
 |
 +-- HIT -> response
 |
 MISS
 |
 v
Redis
 |
 +-- HIT -> L1 -> response
 |
 MISS
 |
 v
PostgreSQL
 |
 v
Redis
 |
 v
L1
 |
 v
response

PUT#

PostgreSQL update
       |
       v
Invalidate Redis
       |
       v
Invalidate L1

Add:

  • TTL
  • hit/miss metrics
  • request coalescing
  • timeout
  • fallback
  • hot-key simulation
  • cache warming
  • graceful degradation

65. Testing the Cache#

Test:

Normal hit#

Request -> Cache -> response

Miss#

Request -> Cache MISS -> DB -> Cache -> response

Expiration#

TTL expires -> next request misses

Stampede#

Send many concurrent requests for one expired key.

Expected:

One backend load
Many shared responses

Redis failure#

Stop Redis.

Expected:

Fast failure/fallback
No uncontrolled database explosion

Database failure#

Test behavior when both cache and database cannot provide fresh data.

Expected behavior should be defined by business requirements.


66. Master Mental Model#

At advanced level, think about caching as six layers:

                CACHE SYSTEM
                     |
       +-------------+-------------+
       |             |             |
     SPEED        CAPACITY      FRESHNESS
       |             |             |
      L1         Partitioning   TTL
      L2         Sharding       Invalidation
      CDN        Replication    Refresh
       |             |             |
       +-------------+-------------+
                     |
                 RELIABILITY
                     |
          +----------+----------+
          |          |          |
       Failover   Timeout   Fallback
                     |
                 PROTECTION
                     |
          +----------+----------+
          |          |          |
       Stampede   Hot Key   Rate Limit
                     |
                OBSERVABILITY
                     |
          Hit Ratio / Latency /
          Memory / Evictions /
          Errors / Hot Keys

When designing a cache, do not stop at:

"We'll use Redis."

Instead explain:

What
Why
Where
How
TTL
Invalidation
Partitioning
Replication
Failure
Capacity
Consistency
Observability
Security

That is production-grade cache thinking.


67. Chapter Summary#

In this chapter, we learned:

  • Redis architecture and use cases
  • Redis strings, hashes, sets, sorted sets, lists, and streams
  • Redis expiration
  • Redis persistence considerations
  • distributed cache clusters
  • cache partitioning
  • cache replication
  • cache failover
  • distributed locks
  • lock expiration
  • fencing tokens
  • request coalescing
  • stale-while-revalidate
  • refresh-ahead
  • TTL jitter
  • probabilistic early refresh
  • hot-key mitigation
  • multi-region caching
  • regional consistency
  • cache warming
  • cache observability
  • cache capacity
  • eviction strategies
  • Redis sessions
  • distributed counters
  • rate limiting
  • cache security
  • cache failure handling
  • timeouts
  • circuit breakers
  • graceful degradation
  • multi-level cache architecture
  • production cache design
  • advanced interview scenarios

The central idea is:

At scale, the cache itself becomes a distributed system. You must design its partitioning, replication, consistency, failure handling, capacity, and observability—not merely choose a cache technology.


68. Final Interview Checklist#

Make sure you can explain:

  • Redis use cases
  • Redis data structures
  • Cache partitioning
  • Cache replication
  • Cache cluster
  • Cache failover
  • Distributed locks
  • Lock expiration
  • Fencing tokens
  • Request coalescing
  • Cache stampede prevention
  • Stale-while-revalidate
  • Refresh-ahead
  • TTL jitter
  • Hot-key mitigation
  • Multi-region cache
  • Cache warming
  • Cache observability
  • Cache capacity planning
  • Redis sessions
  • Distributed counters
  • Redis-based rate limiting
  • Cache timeout
  • Circuit breaker
  • Graceful degradation
  • Cache security
  • Multi-level caching
  • Production failure scenarios

69. What's Next?#

Chapter 17 — Storage Systems#

Next we move beyond databases and caches into large-scale storage systems.

We will learn:

  • What storage systems are
  • Block storage
  • File storage
  • Object storage
  • Local vs network storage
  • HDD vs SSD
  • IOPS
  • Throughput
  • Latency
  • Storage durability
  • Replication
  • Erasure coding
  • Object storage architecture
  • Metadata services
  • File systems
  • Distributed file systems
  • Storage tiers
  • Hot/warm/cold data
  • Data lifecycle management
  • Large-file storage
  • Media storage
  • Upload/download architecture
  • Pre-signed URLs
  • CDN + object storage
  • Storage reliability
  • Backup and archival
  • Production storage architecture
  • System-design interview questions

Finished this chapter?

Mark it as complete to track your mastery.

Previous ChapterChapter 15 — Caching FundamentalsNext ChapterChapter 17 — Storage Systems
PrevNext