Caching: Redis vs Memcached vs Local Cache
Cache-aside, Write-through, Write-back, Read-through. Keep frequently requested data in fast memory so that the request never has to reach the DB.
9.1 Why is it used?
- Fetching data from the DB takes 5-50 ms, while a RAM cache takes well under 1 ms -> response time becomes very fast.
- On sale day lakhs of people view the same product page; without a cache the DB would get so much load that it would go down.
- DB read queries drop by 80-95%, so even a small and cheap DB can cope.
- You get a fast shared store for temporary things like sessions, login tokens and carts.
9.2 How it works
- Local / in-process cache: lives in the app server's own RAM (Caffeine, Guava, Python dict). Fastest, but every server has its own separate copy.
- Distributed cache: a separate cache cluster (Redis, Memcached) shared by all app servers.
- Cache-aside (lazy loading): the app checks the cache first; on a miss it reads from the DB and puts the value in the cache. The most common pattern.
- Read-through: the app talks only to the cache; on a miss the cache itself loads data from the DB (DAX, NCache, Caffeine loader).
- Write-through: a write goes to the cache and to the DB together -> data is always in sync, but writes are a little slower.
- Write-back (write-behind): a write goes only to the cache and reaches the DB later in batches -> very fast, but there is a data loss risk if the cache crashes.
- Write-around: a write goes straight to the DB and skips the cache -> good for data that is rarely read.
- Cache hit ratio: the percentage of requests served from the cache; 90%+ is considered good.
- 1.App: request arrives, check the cache first
- 2.Cache hit: return the value directly (1 ms)
- 3.Cache miss: read from the DB
- 4.Put the DB data in the cache with a TTL
- 5.Send the response to the user
In write-through a write goes to both cache and DB; in write-back only to the cache and to the DB later
9.3 Tools
| Tool | Type | How it is used |
|---|---|---|
| Redis | In-memory data store | Strings, hash, list, sorted set, TTL, persistence, replication -> the most popular distributed cache and session store. |
| Memcached | In-memory key-value cache | Simple, multi-threaded, string key-value only. Facebook used it at large scale. |
| Caffeine / Guava (Java), lru_cache (Python) | Local in-process cache | Keeps data in RAM inside the app itself, so no network call is needed. |
| AWS ElastiCache / Azure Cache for Redis / GCP Memorystore | Managed cache | Runs Redis/Memcached as a managed service in the cloud; the cloud handles patching and failover. |
| Amazon DynamoDB DAX | Read-through/write-through cache | A microsecond-latency cache in front of DynamoDB, with very few app code changes. |
| CDN (CloudFront, Akamai) | Edge cache | Images, JS, CSS and static pages are cached on a server close to the user. |
9.4 Comparison: Redis vs Memcached vs Local (in-process) Cache
| Point | Redis | Memcached | Local Cache |
|---|---|---|---|
| Speed | Sub-millisecond, a network hop is involved | Sub-millisecond, a network hop is involved | Fastest, nanoseconds-microseconds, no network |
| Data types | String, hash, list, set, sorted set, stream | Only string/blob | Whatever objects the language supports |
| Persistence | Yes, RDB snapshot and AOF | No, everything is lost on restart | No, lost when the process restarts |
| Threading | Main command processing is single-threaded (I/O threads from 6.0) | Multi-threaded | Runs with the app's threads |
| Sharing | Shared by all servers | Shared by all servers | Separate copy per server, inconsistency possible |
| Replication / HA | Replica, Sentinel, Redis Cluster | No built-in replication | None |
| Extra features | Pub/Sub, Lua, TTL, locks, leaderboard | Just get/set/TTL | Size limit, TTL |
| Best for | Session, cart, leaderboard, rate limit, general cache | Simple large HTML/object cache | Config, hot small data, L1 cache |
9.5 When to choose which
- Redis: when you need data structures, persistence, replication or pub/sub -> the default choice in most cases.
- Memcached: when you only need a simple key-value cache and want more throughput from multiple cores.
- Local cache: very hot data that rarely changes (config, category list) -> used as an L1 cache in front of Redis.
- Cache-aside: for general read-heavy apps; write-through: when cache and DB must always be in sync; write-back: for write-heavy counters/analytics where a little data loss is acceptable.
9.6 Real-world example
Flipkart Big Billion Day product page (an illustrative scenario)
- As soon as the sale starts, a popular phone's page gets 2 lakh requests in 1 second.
- The app server first looks for the product details in its local Caffeine cache (L1, TTL 5 sec).
- If not found there, it checks the key product:12345 in the Redis cluster (L2).
- On a Redis hit the response goes out in 1 ms; 95%+ of requests end here.
- On a miss it reads from MySQL and puts the data in Redis with a 10 min TTL (cache-aside).
- When the price is updated, the app updates the DB and deletes the Redis key so that the next read loads fresh data.
- Result: the DB sees only a few thousand QPS, not lakhs -> the site keeps running.
9.7 Interview tips
- Caching everything is a mistake: caching data that is not read repeatedly just wastes RAM.
- Treating the cache as the source of truth is a mistake: the cache can be empty at any time, the DB holds the real data.
- Interview tip: always explain the difference between cache-aside and write-through and the consistency trade-off.
- With write-back a cache crash = data loss; so do not use write-back for payments/orders. A number worth quoting: cache hit ratio 90%+, and DB 5-50 ms vs cache under 1 ms.