High-Level Design Tutorial 0/42 lessons ~6 min read Lesson 21

    Cache Strategies

    Caching stores copies of expensive computation or data closer to consumers — in-process, Redis, or CDN.

    Course progress0%
    Focus
    10 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Caching stores copies of expensive computation or data closer to consumers — in-process, Redis, or CDN. Cache strategies define who reads/writes the cache and when: cache-aside, read-through, write-through, write-back, and refresh-ahead. Wrong strategy causes stale data, lost writes, or thundering herds.

    HLD interviews expect you to pick a strategy per data type, explain invalidation, and handle cache failure (fail open vs closed). Product catalog tolerates staleness; inventory and pricing need tighter consistency.

    This lesson maps strategies to use cases and failure modes.

    Understanding the topic

    Key concepts

    • Cache-aside (lazy): app manages cache; most flexible, common in microservices.
    • Read-through: cache library loads on miss — simpler app code.
    • Write-through: write cache and DB synchronously — consistent but slower writes.
    • Write-back (write-behind): write cache first, async flush to DB — fast, data loss risk.
    • Invalidation: TTL, event-driven purge, versioned keys (product:v42:id).
    • Cache stampede: many misses on expiry — mitigate with jitter, single-flight lock.
    text
    flowchart LR
    App -->|1 read| Cache
    Cache -->|2 miss| DB
    DB -->|3 populate| Cache

    Internal architecture

    Architecture overview

    text
    flowchart LR
    App -->|1 read| Cache
    Cache -->|2 miss| DB
    DB -->|3 populate| Cache

    Step-by-step explanation

    1. Hot read path: CDN → Redis → DB for three-tier caching.
    2. On product update: publish ProductUpdated event → consumers DEL cache keys.
    3. Negative caching: cache 'not found' briefly to protect DB from scrapers.
    4. Local in-process Caffeine cache L1 + Redis L2 for ultra-hot keys.
    5. Circuit breaker on Redis failure: fall through to DB with rate limit.
    6. Warm cache on deploy via background loader for top 10k SKUs.

    Informative example

    Write-through vs cache-aside — Spring cache eviction on update with single-flight miss protection:

    java
    @Service
    public class PricingService {
    private final StringRedisTemplate redis;
    private final PriceRepository db;
    public PricingService(StringRedisTemplate redis, PriceRepository db) {
    this.redis = redis;
    this.db = db;
    }
    public BigDecimal getPrice(String sku) {
    String key = "price:" + sku;
    String val = redis.opsForValue().get(key);
    if (val != null) return new BigDecimal(val);
    synchronized (("lock:" + sku).intern()) {
    val = redis.opsForValue().get(key);
    if (val != null) return new BigDecimal(val);
    BigDecimal price = db.findPrice(sku);
    redis.opsForValue().set(key, price.toPlainString(), Duration.ofMinutes(5));
    return price;
    }
    }
    @Transactional
    public void updatePrice(String sku, BigDecimal price) {
    db.save(sku, price);
    redis.delete("price:" + sku); // invalidate, not write-through unless required
    }
    }

    Single-flight reduces stampede. Financial pricing may need write-through or shorter TTL + event invalidation.

    Real-world use

    Real-world use cases

    • E-commerce: CDN for images, Redis for prices, Caffeine for config flags.
    • Banking FX rates: read-through with 60s TTL and admin purge.
    • OTT: manifest cache short TTL; segment cache long TTL at CDN.
    • Social graph: write-back too risky — cache-aside follower lists with event invalidation.

    Best practices

    • Classify data: immutable (long TTL), soft stale OK (minutes), must-fresh (no cache or seconds).
    • Use TTL jitter on popular keys.
    • Monitor hit rate, miss latency, eviction rate.
    • Version keys on schema change — avoid deserialization errors.
    • Document cache failure behavior in runbooks.
    • Load test with cold cache scenario.

    Common mistakes

    • Caching without invalidation on write — stale prices forever until TTL.
    • Write-back without durability plan — data loss on crash.
    • Caching personalized responses keyed wrong — privacy leak.
    • Infinite TTL on mutable data.
    • Ignoring thundering herd on hot key expiry during sales.

    Advanced interview questions

    Q1BeginnerWhat is cache-aside?
    Application reads cache first; on miss loads DB and populates cache manually.
    Q2BeginnerWrite-through vs write-back?
    Write-through syncs cache and DB on write; write-back delays DB write for speed with loss risk.
    Q3IntermediateHow prevent cache stampede?
    TTL jitter, mutex/single-flight, stale-while-revalidate, probabilistic early refresh.
    Q4IntermediateCache fail open or closed?
    Open: bypass to DB (risk overload); closed: error — choose by dependency criticality and DB headroom.
    Q5AdvancedCache strategy for flash sale inventory?
    Short TTL cache-aside insufficient — use Redis DECR atomic stock, DB async reconcile, no pure cache for authoritative count.

    Summary

    Pick cache strategy per data consistency needs. Cache-aside is default; write-through for strong sync requirements. Invalidation via TTL, events, or versioned keys. Stampede protection is mandatory on hot keys. Multi-tier: CDN, Redis, local cache. Message queues decouple cache warming and async invalidation.

    Ready to mark this lesson complete?Track your journey across the entire course.