1. How would you design a caching server?
Define the client-facing operations, cache-key boundary, source-of-truth interaction, expiration and eviction behavior, concurrency, failure handling, and observability. Explain what clients should observe when an item is absent, expired, stale, or temporarily unavailable, without assuming a particular cloud provider.
At a high level, the goal is to return frequently used data very quickly. The main challenge is keeping reads fast while handling missing, expired, stale, and unavailable entries correctly. I would explain the design through the request path, the cache and source-of-truth path, and the failure and operations path. Clients use get, set, and delete operations. Cache misses read from the source of truth. The main trade-off is faster access in exchange for expiration, eviction, and consistency complexity.
The goal is to keep commonly requested data close to applications so clients get fast answers. The hard part is deciding what happens when an item is missing, old, removed, or temporarily unavailable. The system must also handle many requests at once without losing control of memory. The diagram organizes this into the client request path, the in-memory cache path, the Source of Truth path, and the operational paths for expiration, failures, scaling, and monitoring. Each get, set, or delete operation targets one cache key and its value.
- Which get, set, and delete behavior must clients support?
- How long may cached values stay valid?
- Is serving stale data allowed during refresh or failure?
- Should writes use write-through or write-back behavior?
- What should clients receive when the cache or Source of Truth is unavailable?
I would start with how a request enters the system. Clients can be web or mobile applications, services, microservices, SDKs, or command-line tools. They send get, set, or delete requests through the Edge & API Layer.
That layer terminates TLS, checks authentication, validates requests, applies rate limits, and balances load. The request then reaches a horizontally scalable Caching Server node. The response returns to the client as a value or status.
Each operation targets one cache key. That key identifies one entry inside the cache, while the Source of Truth remains responsible for the official data.
Inside a Caching Server node, the Request Router sends work to the Protocol Handler. The Concurrency & Thread Pool handles many requests, using asynchronous I/O where appropriate. The Cache Engine keeps cached values in memory for low latency.
On a cache hit, the value returns without reading the Source of Truth. If an item is absent or expired, the cache treats it as a miss. It reads the value from the Source of Truth, stores the returned value in cache, and serves it to the client.
Expiration can use a per-item TTL, which means a time limit, or an idle timeout. LRU, LFU, or TTL-based eviction can remove entries when needed. A background sweeper removes expired items, and size-based eviction protects memory limits.
For writes, the diagram allows configurable write-through or write-back behavior. Changes can invalidate or update cached data so clients do not keep using an unwanted old entry.
If stale serving is allowed, an old value may be returned while the system refreshes it in the background. An expired item is otherwise treated as a miss. An absent item causes a Source of Truth read before the value is cached and returned.
If the cache is unavailable, the system can fall back to the Source of Truth with rate limiting, or return an error. Timeouts may return stale data when allowed. Otherwise, the client receives an error instead of incorrect data.
If one cache node fails, traffic goes to healthy nodes. Retries use exponential backoff and jitter, which spaces retries apart. A circuit breaker stops repeated failing requests from overwhelming the Source of Truth.
The cache nodes scale horizontally. Monitoring includes hit rate, QPS, latency, errors, evictions, logs, traces, dashboards, and alerts. The benefit is fast access and a high hit rate. The downside is extra work around freshness, memory limits, failures, security, and cost.
The benefit is very fast access because hot data stays in memory. Adding cache nodes also helps the service handle more requests. The downside is that cached data can become old, expire, or be removed when memory is full. Short TTLs give fresher data but cause more reads from the Source of Truth. Longer TTLs reduce those reads but may keep old values longer. Serving stale data can improve availability, but clients may briefly see older information. Write-through is easier to reason about. Write-back can reduce write delay, but it adds more failure risk.
Interviewers ask this to see whether you can design a fast system without forgetting correctness and operations. They want to see how you handle cache keys, hits, misses, expiration, eviction, concurrency, failures, and the Source of Truth. They also look for judgment about stale data, rate limits, retries, scaling, security, monitoring, and the trade-off between speed and fresh data.









