Store frequently accessed data in fast storage (memory) to reduce latency, database load, and network calls. The single most impactful optimization in any system.
Easy Very High FrequencyThe application sits between the cache and the database. On every read, it first checks the cache. On a hit, data is returned instantly (~ฮผs). On a miss, the app queries the database, stores the result in the cache, and returns it to the client.
App manages the cache explicitly. Read: check cache โ miss โ read DB โ write cache. Write: update DB โ invalidate cache. Most common strategy. Risk: stale data if invalidation fails.
Every write goes to cache AND database synchronously. Guarantees cache consistency. Downside: write latency increases (two writes per operation). Good for read-heavy workloads.
Write to cache immediately, async flush to DB. Ultra-low write latency. Risk: data loss if cache node dies before flush. Used in hardware (CPU caches) and disk controllers.
Cache itself handles DB reads on a miss (cache sits in front of DB). Simplifies app code โ it only talks to cache. Requires cache library support (e.g., NCache, Hazelcast).
When a popular cache key expires, hundreds of requests simultaneously hit the DB. Solutions:
Local cache vs Distributed cache: Local (in-process) cache is fastest (~ns) but not shared across instances โ leads to inconsistency. Distributed cache (Redis, Memcached) adds ~1ms network hop but is shared and consistent. Most systems use both: L1 local + L2 distributed.
TTL tuning: Too short = high miss rate, defeating the purpose. Too long = stale data. Match TTL to how often the underlying data changes. User profiles: minutes. Stock prices: seconds. Static assets: hours/days.
Invalidation vs TTL: Active invalidation (delete on write) gives freshness but adds complexity. TTL is simpler but allows staleness windows. Phil Karlton: "There are only two hard things in CS: cache invalidation and naming things."
Redis vs Memcached: Redis: data structures (lists, sets, sorted sets), persistence, pub/sub, Lua scripting. Memcached: simpler, multi-threaded, slightly faster for plain key-value. Redis wins for 90% of use cases.
Caching is relevant in almost every system design interview. Mention it whenever you see:
Interview signal: The interviewer wants to hear you discuss what to cache, where to cache it, when to invalidate, and how to handle failures (cache down โ system down).
| Metric | Value |
|---|---|
| Redis GET latency | ~0.1โ0.5 ms |
| Redis throughput (single node) | ~100Kโ200K ops/sec |
| Memcached throughput | ~200Kโ700K ops/sec |
| L1 CPU cache access | ~1 ns |
| In-process cache (HashMap) | ~50โ100 ns |
| Redis (same AZ, network) | ~0.1โ1 ms |
| Database query (indexed) | ~1โ10 ms |
| Database query (full scan) | ~100โ1000 ms |
| Typical cache hit ratio (healthy) | 95โ99% |