Sign in to keep reading
“Distributed Caching” is free with an account. Your progress and bookmarks follow you across devices.
Sign in to continueNEW: ML Mock & Coaching with a 20+ year experience coach. Save $20 on sessions for Premium.ML Mock & Coaching now available
NEW: ML Mock & Coaching with a 20+ year experience coach. Save $20 on sessions for Premium.ML Mock & Coaching now available
Design and operate shared, horizontally scalable caches with Redis data structures, eviction policies, and high availability.
“Distributed Caching” is free with an account. Your progress and bookmarks follow you across devices.
Sign in to continueAlmost every system design question involves caching somewhere. In the Distributed Cache question, you design a full Redis-like system from scratch. In Leaderboard, Redis Sorted Sets power real-time rankings. In Uber, Redis GEO commands find nearby drivers. The pattern keeps showing up because a single-server in-process cache has two fatal problems: it disappears on restart, and it is not shared across multiple application servers.
A distributed cache solves both. It runs as a separate, shared tier that every app server can access over the network. Think of it as a fast, shared scratchpad sitting between your application and your database. When it works well, the database barely notices traffic at all.
The core flow is simple. Your app checks the cache first. If the key exists (cache hit), it returns in under a millisecond — the database is never touched. If the key is missing (cache miss), the app falls through to the database, gets the data, and writes it into the cache so the next request is fast.
Here is the key insight: in a well-tuned system, 95%+ of reads are cache hits. That means your database handles only a fraction of the actual traffic. This is exactly how the Scaling Reads layered caching funnel works — CDN handles static assets, Redis handles dynamic data, and the database sees only what falls through both layers.
There are three main strategies for keeping the cache and database in sync:
| Cache Invalidation Strategies | ||
|---|---|---|
| Strategy | How It Works | Best For |
| Cache-aside | App checks cache first. On miss, reads DB, then writes result to cache with a TTL | Most use cases — simple, and if the cache goes down, reads just fall through to the DB |
| Write-through | Every write updates both DB and cache at the same time | When users must always see their latest data immediately after writing |
| Write-behind | Writes go to cache only; a background job flushes to DB later | Rarely used — fast writes but risky if cache crashes before flush |
Cache-aside is the default choice. It is simple, resilient (cache failure means slower, not broken), and naturally adapts to access patterns — only frequently-read data stays cached.
See it in practice: The Distributed Cache question walks you through designing a full caching system with these invalidation strategies. The Scaling Reads pattern shows where caching fits in the broader read-scaling progression. In Yelp, restaurant data is cached with cache-aside to avoid repeated database lookups on every page view.
Most people think of Redis as a simple key-value store, but its rich data structures are what make it so powerful for system design. Each structure is purpose-built for specific access patterns:
| Redis Data Structures | ||
|---|---|---|
| Data Structure | What It Does | Use Cases |
| String | Simple key-value pairs, atomic counters | Cache entries, rate limiting counters, feature flags |
| Hash | A dictionary under a single key | User sessions, object fields without serialization overhead |
| List | Ordered collection with push/pop from both ends | Message queues, activity feeds (FIFO/LIFO) |
| Set | Unordered collection of unique values | |
The key takeaway: when you hear "cache" in a system design interview, don't just think GET and SET. Ask yourself which data structure fits the access pattern. A Leaderboard naturally maps to Sorted Sets. An Uber driver location system naturally maps to GEO commands. A Slack unread-count tracker maps to Hashes.
See it in practice: In Leaderboard, ZADD and ZRANGEBYSCORE on a Sorted Set power real-time ranking at scale. In Uber, GEOADD and GEORADIUS find nearby drivers within milliseconds. In Distributed Counters, atomic INCR on Strings handles high-throughput counting without race conditions.
| Unique visitor tracking, tag systems, mutual friends |
| Sorted Set | Set where each member has a numeric score | Leaderboards, priority queues, range queries by score |
| Bitmap | Bit-level operations on strings | Daily active users, feature flags per user |
| HyperLogLog | Probabilistic unique-count estimation | Approximate unique visitors (12KB regardless of cardinality) |
| Stream | Append-only log with consumer groups | Event sourcing, message queues with acknowledgment |
| GEO | Geospatial indexes with radius queries | Proximity queries for drivers, restaurants, stores |