Caching Interview Questions for Backend Engineers: Eviction, Stampedes, and Consistency
Quick Overview
Learn a practical backend caching interview framework for eviction policies, cache stampedes, consistency, TTLs, invalidation, and failure handling.
A cache failure rarely announces itself as a cache failure. It appears as a database spike after a deployment, a flood of identical requests when one popular key expires, or a customer seeing an older value moments after a successful update.
That is why strong caching interview answers go beyond "use Redis" or "pick LRU." Interviewers want to hear how you define freshness, protect the source of truth, choose an eviction policy from the workload, and keep a cold or unavailable cache from turning into a system-wide outage.
Start with PracHub's Backend Engineer interview questions if you want company and role context while you practice. This guide gives you the reasoning framework to apply when those questions introduce TTLs, invalidation, hot keys, or downstream failures.

Quick answer: use an eight-step caching framework
A good answer starts with the workload and ends with failure behavior. Use this sequence instead of jumping directly to a product or policy:
- Name the source of truth. State which database or service owns the authoritative value.
- Define the cache key and scope. Explain whether the cache is per process, shared across a fleet, per user, or global.
- Describe the workload. Estimate read/write ratio, reuse, object size, access skew, and acceptable latency.
- Set the freshness contract. Say how stale a value may be and whether any reads require read-after-write freshness.
- Choose the loading and write path. Compare cache-aside, read-through, write-through, and write-behind.
- Choose expiration and eviction separately. TTL manages age; eviction manages bounded capacity.
- Protect misses and refreshes. Add request coalescing, jitter, stale serving, negative caching, and backpressure where justified.
- Explain failure and measurement. Cover cold starts, cache outages, source protection, hit rate, evictions, stale serves, and downstream request volume.
This order makes your assumptions visible. It also stops a common interview mistake: optimizing hit rate before deciding whether a stale hit is correct.
What interviewers are actually evaluating
Caching questions test whether you can turn a latency optimization into a complete reliability design. The best candidates connect correctness, capacity, traffic shape, and operability rather than discussing each one in isolation.
Expect follow-ups that change one constraint. What if writes become frequent? What if one key receives 20 percent of traffic? What if the cache is flushed during a deploy? What if serving stale payment data is worse than returning an error? A strong design changes when those answers change.
Interviewers also listen for explicit trade-offs. "Five-minute TTL" is not a design decision until you explain why five minutes fits the source's update rate, the user's staleness tolerance, and the load the source can absorb during refresh.
Expiration and eviction solve different problems
Expiration removes or refreshes an item because it has become too old. Eviction removes an item because the cache has reached a capacity limit. A key can be fresh and still be evicted, or stale and remain present until it is accessed if expiration is lazy.
Keep the two controls separate in your answer. A TTL should come from a freshness requirement; an eviction policy should come from the access distribution, object cost, and memory budget.
| Policy | When it fits | Risk to discuss |
|---|---|---|
| LRU | Recent access predicts near-future reuse | A scan can displace genuinely hot items; exact recency also adds metadata and mutation cost |
| LFU | Long-lived popularity matters more than recency | Old popularity can linger unless counters decay as the workload changes |
| FIFO or random | Simplicity and low bookkeeping matter, or accesses are close to uniform | Useful entries may be removed without considering recency or frequency |
| Shortest TTL first | The application already assigns meaningful expirations | It is only as good as the TTL policy and may ignore access value |
| No eviction | Rejecting writes is safer than losing cached or mixed-purpose data | Callers must handle write failures and capacity alarms before the limit |
Why LRU is a starting point, not a universal answer
LRU works well when a relatively small working set receives most requests and recent use predicts reuse. It is less attractive for sequential scans, bursty one-time objects, or workloads where a frequently used item can go quiet briefly and should still remain cached.
Production systems may approximate LRU or LFU to reduce metadata and CPU cost. In an interview, it is enough to say whether exact ordering is required, what approximation buys you, and which metric would tell you that the policy is evicting the wrong keys.
Capacity should usually be measured in bytes
An entry-count limit treats a 20-byte flag and a 5-megabyte response as equal. For variable-sized objects, track key, value, and metadata bytes. You can then discuss weighted eviction or reject any item larger than the entire cache budget.
How cache stampedes happen
A cache stampede occurs when many requests discover the same missing or expired key at nearly the same time and all fetch the value from the source. The cache was meant to protect that dependency, but synchronized misses suddenly multiply its traffic.
Common triggers include a popular key reaching one fixed TTL, a fleet-wide cache flush, a deployment that starts many empty local caches, or an outage that removes a shared cache. The important insight is that a 95 percent hit rate does not prove safety: the remaining misses may be highly correlated.
Use single-flight request coalescing
For each key, allow one request to become the loader while the others wait for its result. The coordination can be local when the cache is local or implemented with a bounded distributed lease when many application instances share a cache.
The lock needs a timeout and an owner token. If the loader crashes, another request must eventually continue; if an expired owner finishes late, it should not overwrite a newer value. This is why "put a lock around it" is incomplete without lease expiry and write validation.
Spread refresh work instead of moving the spike
Add random jitter to TTLs so thousands of keys do not expire on the same boundary. For high-value keys, refresh before hard expiration. A soft TTL can trigger background refresh while a hard TTL defines the last point at which the old value may be served.
Negative caching can also protect the source. Cache a missing resource or a deterministic error for a shorter, separate TTL so repeated requests do not keep asking a struggling dependency the same question.

Consistency starts with a freshness contract
Every cache duplicates data, so consistency is not a toggle. Define what the reader may observe. A product description might tolerate minutes of staleness, while an authorization decision or account balance may require a fresh source read or a much stricter invalidation path.
Cache-aside is common: read the cache, load the source on a miss, then populate the cache. On a write, update the source and invalidate the cached entry. It is simple and lets the application control fallback behavior, but it does not guarantee that the cache and source always match.
Write-through updates the cache as part of the write path and can improve read-after-write behavior. It adds latency and couples write availability to the cache path. Write-behind acknowledges before the source is fully updated, which improves throughput but risks data loss, reordering, and harder recovery; do not propose it for authoritative data without a durable queue and explicit semantics.
Invalidate after the database commit
With cache-aside, update the source first and invalidate the cache after the commit. If you delete the cache first, a concurrent reader can miss, read the old database value, and repopulate the stale entry before the write commits.
Even update-then-delete has a narrower race: a reader may begin an old source read before the commit and fill the cache after invalidation. Depending on the required guarantee, you can use versioned values, compare a source version before filling, perform a delayed second invalidation, or route the writer's next read around the cache.
Worked scenario: caching a product details API
Assume GET /products/{id} reads a database record that changes a few times per day. Traffic is read-heavy, popular products are highly skewed, p99 must stay below 100 ms, and most clients can accept data that is up to two minutes old.
Use a shared cache with a key such as product:v3:{id}. Cache-aside keeps the database authoritative. Set a soft TTL near 90 seconds, a hard TTL near 120 seconds, and add jitter so expiration work spreads over time. Single-flight ensures one loader per product key.
Choose LRU or LFU only after measuring the access distribution. LRU is reasonable if trending products change quickly; LFU with decay can work better if popularity persists. Bound memory by bytes and avoid caching oversized responses that would evict many useful items.
On an update, commit the database transaction, then invalidate the key. Include a record version in the cached payload and reject a fill older than the latest known version. For an editor who must immediately see the update, bypass the cache once or request a version at least as new as the completed write.
If the cache is unavailable, do not let every request fall through without a limit. Cap database concurrency, shed optional traffic, serve a last-known value only within the hard-staleness policy, and alert on the sudden change in downstream QPS.
Failure modes and metrics belong in the answer
A cache creates two operating modes: hit and miss. Test both. A deployment, node replacement, bad serialization change, or cache outage can shift a large percentage of traffic into the expensive mode within seconds.
Track hit and miss rate by endpoint and key class, not only globally. Add eviction rate, expiration rate, fill latency, fill errors, single-flight waiters, stale responses, object size, memory pressure, and downstream QPS. A high hit rate can still hide one expensive key family with a damaging miss pattern.
Also explain the cache-down policy. Unlimited fallback can brown out the source; fail-closed can reduce availability; serving stale data can violate correctness. Pick by data class, then enforce the decision with timeouts, bounded concurrency, load shedding, and a tested recovery path.
Practice caching questions on PracHub
These questions exercise eviction invariants, TTL semantics, source protection, and implementation details. Use the stored prompt and role as practice context; no question bank can predict an exact future interview.
| PracHub question | Practice focus | Why it helps |
|---|---|---|
| Find Bugs in an LRU Cache | Recency, eviction, and minimal tests | Forces you to state the LRU invariant and catch behavior that compilation cannot prove. |
| Execute a TTL Key-Value Store with Transactions | TTL, logical time, and rollback | Builds precise expiration semantics and resource-aware implementation reasoning. |
| Design a Resilient Bootstrap API | Staleness, fallbacks, and thundering herd | Connects caching decisions to dependency protection and degraded service behavior. |
| Design a Single-Node Persistent In-Memory Cache | LRU, concurrency, and durability | Tests concrete data structures, locking, bounded memory, and recovery trade-offs. |
A seven-day caching interview plan
| Day | Focus | What to do |
|---|---|---|
| Day 1 | Workload and freshness | Define source of truth, key scope, reuse, staleness tolerance, and failure cost for two APIs. |
| Day 2 | Eviction | Compare LRU, LFU, and TTL-based choices under skew, scans, and variable object sizes. |
| Day 3 | Expiration | Design soft and hard TTLs, jitter, proactive refresh, and negative caching. |
| Day 4 | Stampedes | Implement or explain single-flight with lease timeout, owner token, and loader failure. |
| Day 5 | Consistency | Trace concurrent cache-aside reads and writes; repair the stale-repopulation race. |
| Day 6 | Failure and metrics | Plan cache-down behavior, source limits, load shedding, alarms, and a cold-cache test. |
| Day 7 | Mock interview | Deliver the eight-step framework on one API and defend every TTL and fallback. |
Frequently asked questions
What is the difference between cache eviction and expiration?
Eviction removes entries to stay within a capacity budget. Expiration marks entries too old to serve or refreshes them according to a freshness policy. Capacity pressure and data age are different decisions.
Is LRU always the best eviction policy?
No. LRU fits workloads where recent access predicts reuse. LFU may retain persistent hot items better, while simpler policies can reduce bookkeeping. Choose from measured access patterns and validate with miss and eviction metrics.
How do you prevent a cache stampede?
Coalesce concurrent misses so one request loads each key. Add TTL jitter, proactive refresh, soft and hard expirations, negative caching, and source backpressure as the workload requires.
How do you keep a cache consistent with a database?
First define the required consistency. A common cache-aside path commits the database write, then invalidates the cache. Stricter requirements may need version checks, write-through behavior, or a cache bypass after a write.
Should the service fall back to the database if Redis is down?
Only with protection. Bound concurrency and request rate so fallback traffic cannot overwhelm the database. Depending on the data, you may also serve a limited stale value, shed optional work, or fail closed.
Which cache metrics matter most in an interview answer?
Start with hit and miss rate, eviction and expiration rate, fill latency and errors, memory and object size, stampede waiters, stale serves, and downstream QPS. Segment them by endpoint or key class.
Final takeaway
The strongest caching interview answer is a correctness and load-shaping argument, not a Redis feature list. Define the source of truth and freshness contract, choose expiration and eviction for different reasons, collapse correlated misses, and say exactly what happens when the cache is cold or unavailable.
Practice that reasoning on PracHub's Backend Engineer question bank. For each prompt, state your assumptions, draw the read and write races, defend one policy, and name the metric that would prove it works.
Sources and Further Reading
- Redis: Key Eviction Policies
- AWS Builders' Library: Caching Challenges and Strategies
- Microsoft Azure Architecture Center: Cache-Aside Pattern
Research note: This guide was checked on August 22, 2026. Cache capabilities and operational behavior vary by product, client library, and workload.
Related Articles
小林coding 够用吗?后端八股到真实面试实战的差距
小林coding准备后端面试够用吗?本文分析图解八股的优势、真实面试中的Coding与系统设计差距,并给出7天实战训练路线。
Distributed Lock Interview Questions: Leases, Fencing Tokens, and Failure Modes
Prepare for distributed lock interviews with leases, fencing tokens, stale-writer protection, Redis and etcd trade-offs, and failure walkthroughs.
Microservices Interview Questions: Boundaries, Failure Handling, and Data Ownership
Prepare for microservices interviews with service boundaries, failure handling, data ownership, sagas, outbox patterns, and a worked checkout design.
Message Queue Interview Questions: Ordering, Retries, Delivery Semantics, and DLQs
Prepare for message queue interviews with ordering, retries, delivery semantics, acknowledgements, idempotency, DLQs, and failure scenarios.
Comments (0)