System Design blueprint · E-Commerce
Cache-aside caching
The most common caching pattern: read through the cache, write to the database, then invalidate.
- Steps
- 5
- Subjective questions
- 32
- Objective questions
- 32
The problem and the outcome
Problem: Product pages hammer the database during a sale and slow every shopper down.
Outcome: Most reads served from memory; the database handles only misses and writes.
Architecture
How it works, step by step
- The app asks the cache first, by a key such as product:42.
- On a hit the value comes straight back from memory, in about a millisecond.
- On a miss the app reads the database, then stores the row in the cache with a TTL.
- Writes go to the database first, then delete the cached key so the next read loads fresh data.
- The TTL caps how stale a value can get if an invalidation is ever missed.
Tech stack
- Redis or Memcached
- Relational database
- TTL per key
- Change-data-capture (Debezium) for invalidation
Key design decisions
- The application owns the cache: read the cache, fall back to the database on a miss, then fill the cache.
- On a write, update the database and then delete the cache key rather than updating it, which avoids stale overwrites from racing writers.
- A TTL on every key, so any missed invalidation heals itself.
Common mistakes
- A cache stampede when a hot key expires and thousands of requests hit the database at once.
- Updating the cache before the database commits, so readers see data that is later rolled back.
- Caching null results without a short TTL, or not caching them at all and letting bad keys hammer the database.
What to measure
- Hit ratio (often 90%+ on read-heavy pages)
- Database QPS saved
- Staleness window after a write
Most-asked interview questions
Subjective questions 32
1Explain cache-aside, write-through and write-behind.Asked almost every time
Cache-aside: the app reads the cache, loads from the database on a miss and invalidates on write; simple, and the cache holds only what is read. Write-through: every write goes to the cache and the database together, so the cache is always warm but writes are slower. Write-behind: writes go to the cache and are flushed to the database later; fast, but data can be lost if the cache dies.
2How do you prevent a cache stampede on a hot key?Asked almost every time
Let one request rebuild the value while others wait or get the stale value: a mutex or single-flight lock per key, early probabilistic refresh before expiry, and TTL jitter so many keys do not expire together.
3When should you add a cache at all?Asked almost every time
When reads are frequent, data changes less often than it is read, the source is slow or expensive, and slightly stale data is acceptable. Measure first: caching adds complexity, staleness and failure modes, so it should solve a proven latency or load problem.
4How do you choose TTLs?Asked almost every time
Base TTLs on how stale each data type may be and how often it changes: seconds for prices or stock, minutes for profiles, hours for reference data. Add jitter, combine with explicit invalidation on writes, and monitor hit rates and staleness complaints.
5What race condition can occur with cache-aside and how do you avoid it?Asked almost every time
A reader misses, reads old data from the database, then a writer updates the database and deletes the key, and finally the reader writes the old value into the cache, which stays stale until expiry. Short TTLs, delayed double deletion, versioned values or write-through with compare-and-set reduce it.
6Why delete the cache key on write instead of updating it?Very often asked
Two concurrent writers can update the cache in the opposite order to the database and leave it permanently wrong. Deleting means the next read loads the committed value. Some teams delete twice (before and shortly after the write) to cover a read that races the commit.
7What is a cache penetration attack and how do you stop it?Very often asked
Repeated requests for keys that do not exist bypass the cache and hit the database every time. Cache negative results briefly (store a 'not found' marker) and use a bloom filter of valid keys to reject impossible lookups early.
8What is cache avalanche?Very often asked
Many keys expiring at the same time, or the cache restarting empty, sends a flood of requests to the database. Prevent it with TTL jitter, warming the cache before traffic, request coalescing, and rate limiting or circuit breakers in front of the database.
9What is request coalescing?Very often asked
When many requests miss the same key at once, only one fetches from the source while the others wait for its result (single-flight). It prevents duplicate work and stampedes on hot keys.
10What should you cache: query results or objects?Very often asked
Caching domain objects by ID is easy to invalidate on writes. Caching query results (lists, search pages) is faster for reads but harder to invalidate, so use shorter TTLs or tag-based invalidation for them.
11How do you invalidate many related keys at once?Very often asked
Use key versioning (include a version number in keys and bump it to invalidate a group), tag sets that list keys per tag, or namespaces with a generation counter. Avoid scanning for keys in production.
12What is stale-while-revalidate?Very often asked
Serve the cached value even after it is stale while refreshing it in the background, so users get fast responses and data updates soon after. It suits data where brief staleness is fine.
13How do multiple cache layers work together?Very often asked
A request may hit a browser cache, a CDN, an in-process cache (very fast, per instance) and a shared cache like Redis before the database. Each layer needs its own TTL and invalidation story; in-process caches are hardest to invalidate across instances.
14How do you cache a paginated list that changes often?Very often asked
Cache the stable parts, such as each item by ID, and cache the ordered list of IDs per page with a short TTL or a version key bumped on writes. Clients then fetch the ID page and hydrate items from the per-item cache, so one edit invalidates one item, not every page.
15How do you handle hot keys that overload a single cache node?Very often asked
Replicate the hot key across several keys with a random suffix and read from one at random, add a small in-process cache with a short TTL in front of Redis, or use client-side caching. Detect hot keys from cache metrics or Redis' hotkeys sampling.
16How do you keep an in-process cache consistent across instances?Often asked
Use short TTLs, broadcast invalidation messages via Pub/Sub when data changes, or limit in-process caching to immutable or rarely changing data.
17How do you size a cache?Often asked
Estimate the working set (hot keys times average value size), add overhead for the data structure, and watch eviction and hit rates in production. A cache that constantly evicts hot keys is too small.
18What should you never cache?Often asked
Highly sensitive data without encryption and access checks, per-user data under shared keys, data that must be strongly consistent (balances during payment), and errors without short TTLs.
19How do you serialise cached values efficiently?Often asked
Use compact formats (JSON for simplicity, MessagePack or Protocol Buffers for size and speed), compress large values, and include a schema version so deployments with changed shapes do not read incompatible data.
20How do you warm a cache?Often asked
Preload the most requested keys before switching traffic (from logs or analytics), or let a canary serve traffic first. Warming avoids a cold-start spike on the database after deploys or failovers.
21What happens when the cache is down?Often asked
Cache-aside apps should treat cache errors as misses and read from the database, protected by timeouts, circuit breakers and rate limits so the database is not overwhelmed.
22How do you measure cache effectiveness?Often asked
Track hit ratio, latency for hits and misses, eviction rate, memory use, key count and database load. A good cache shows high hit ratio for hot paths and reduced database QPS.
23Write-through vs. write-behind: what are the risks?Often asked
Write-through writes to the cache and database synchronously, adding write latency but keeping them consistent. Write-behind writes to the cache and flushes to the database later, which is fast but risks data loss if the cache fails before flushing.
24How do you cache results computed from several data sources?Often asked
Key the result by all its inputs, version each source, and invalidate when any source changes, often by including the source versions in the key. Prefer short TTLs when exact invalidation is impractical, and document the acceptable staleness.
25When would you choose Memcached over Redis?Often asked
Memcached suits a simple, multi-threaded key-value cache of small objects with LRU eviction and no persistence. Redis adds data structures, persistence, replication, pub/sub and Lua scripts, which you want for counters, leaderboards, rate limits or invalidation fan-out.
26How do you cache data that has a per-request permission check?Often asked
Cache the shared data without permissions applied, then apply the user's access check on every read, or include the permission scope in the key. Never cache a response filtered for one user under a key another user can hit.
27What is probabilistic early expiration?Often asked
Each reader recomputes a value slightly before its TTL ends with a probability that rises as expiry nears, so one request refreshes it early instead of many requests missing at once when it expires. It is a lock-free way to avoid stampedes.
28How do you cache per-user data safely?Sometimes asked
Include the user or tenant ID in the key, apply the same authorisation as the source, avoid caching responses with personal data at shared CDN layers, and set Cache-Control: private for browsers.
29What is read-through caching?Sometimes asked
The cache itself loads missing data from the database through a configured loader, so application code only talks to the cache. It centralises logic but ties the cache to the data source.
30How do HTTP caching headers relate to application caching?Sometimes asked
Cache-Control, ETag and Last-Modified let browsers and CDNs cache responses and revalidate cheaply, reducing load before requests even reach your application cache.
31When is caching the wrong fix for slow queries?Sometimes asked
When a missing index, bad query or N+1 pattern is the real cause. Fix the query first; caching a slow query hides the problem and fails badly on cache misses.
32How do you safely change the format of values already in the cache?Sometimes asked
Put a schema version in the key or value, deploy readers that understand both old and new formats, then writers that write the new one, and let old entries expire. Avoid a mass flush at peak, which would hit the database all at once.
Objective questions 32
1In cache-aside, who loads data into the cache on a miss?Asked almost every time
Why: The application reads the database and populates the cache itself; the cache knows nothing about the database.
2What should happen to a cache error in cache-aside?Asked almost every time
Why: The cache is an optimisation, not the source of truth.
3What stops repeated lookups of non-existent keys?Asked almost every time
Why: This is cache penetration.
4What is single-flight request coalescing?Asked almost every time
Why: It prevents cache stampedes.
5What does adding random jitter to TTLs prevent?Very often asked
Why: Staggered expiry spreads the reload work so the database is not hit by a wave of misses.
6Cache avalanche is caused by…Very often asked
Why: TTL jitter spreads expiry.
7Which layer is hardest to invalidate across instances?Very often asked
Why: Each instance holds its own copy.
8What does stale-while-revalidate do?Very often asked
Why: Fast and eventually fresh.
9How do you invalidate a group of keys cheaply?Very often asked
Why: Old keys simply stop being read.
10Which write strategy risks losing data if the cache fails?Very often asked
Why: Writes are flushed later.
11Which data should not be cached casually?Very often asked
Why: Strong consistency is needed.
12What spreads load from one hot cache key?Very often asked
Why: Several copies put the reads on several nodes.
13Probabilistic early expiration prevents…Very often asked
Why: One reader refreshes early, before the crowd misses.
14Which eviction policy does Redis commonly use for a cache?Often asked
Why: For a pure cache, allkeys-lru or allkeys-lfu evicts the least useful keys when memory is full.
15What should be checked before adding a cache for a slow query?Often asked
Why: Fix the root cause first.
16Which header keeps per-user responses out of shared caches?Often asked
Why: Only the browser may cache it.
17Why include a schema version in cached values?Often asked
Why: Prevents reading incompatible values.
18What does cache warming prevent?Often asked
Why: Preload the hot keys.
19Which metric best shows cache effectiveness?Often asked
Why: Pair with database load.
20How should negative results be cached?Often asked
Why: The key may be created later.
21Read-through caching means…Often asked
Why: A loader is configured in the cache.
22Which mechanism spreads invalidations to in-process caches?Often asked
Why: Each instance drops its copy.
23Which store adds data structures and persistence beyond a plain cache?Often asked
Why: Redis supports lists, sets, sorted sets, streams and persistence.
24How should a frequently changing paginated list be cached?Often asked
Why: An edit then invalidates one item rather than every page.
25A result built from three sources should be invalidated when…Often asked
Why: Its correctness depends on every input.
26Responses filtered for one user must not be stored under…Often asked
Why: That would leak one user's data to another.
27Which formats are more compact than JSON for cached values?Sometimes asked
Why: Smaller and faster to parse.
28A cache that constantly evicts hot keys is…Sometimes asked
Why: Watch the eviction rate.
29What should per-user cache keys include?Sometimes asked
Why: Prevents serving one user's data to another.
30ETag headers let clients…Sometimes asked
Why: A 304 avoids resending the body.
31Which race can leave stale data after a write in cache-aside?Sometimes asked
Why: Short TTLs or versioned values help.
32What is a safe way to change cached value formats?Sometimes asked
Why: Gradual expiry avoids a stampede on the database.
Track your progress through every blueprint in your dashboard.
Start learning