Design a medium scale distributed cache system to store static content and reduce backend load. Total cache size ~1TB and use TTL-based caching (stale entries are evicted).
Requests hit the cache first and on miss the content is fetched from origin and cached with TTL.
The APIs are called by the API Gateway.
GET /cache/{key}
Response:
value (the cached content)
ttl_remaining
cache_hit: true | false
PUT /cache/{key}
Request:
value
tts_seconds
DELETE /cache/{key}
Client
API Gateway
Cache Server (all in memory - 1TB)
Backend Server
This is covered by the cache miss from Read path.
When the cache lookup fails or times out we treat it as cache miss so we fetch from backend. Optionally we can write to another healthy node.
In this case the TTL is expired and the cache cannot be refreshed. We can server the data stale with a flag and let the client decide if/how they want to use it.
In this case admins can manually trigger data refresh by invalidating the TTL for a given cache key.
Problem: Cache is limited to 1TB and hot data can crowd out useful entries.
Approach: have TTL-based eviction as baseline and add LRU/LFU when capacity pressure hits.
Tradeoff: simple eviction vs optimal hit rate.
Problem: Many clients miss the same key and the backend gets overloaded.
Approach: We can group the requests for the same key if they happen at once and do a single flight.
Tradeoff: slightly stale reads vs backend protection.
Problem: Cache node failure or timeouts can impact reads.
Approach: Treat the failures as cache misses and fallback on the backend. Additionally we can use replication for hot keys.
Tradeoff: Lower hit rate during failure vs availability.