Cache-Aside vs Write-Through vs Write-Behind Caching Strategies
Fast recall
Quick revision
Core answer
Understanding of caching patterns beyond simple 'cache the result', including trade-offs between consistency, latency, and durability.
Confusing write-through with write-behind, or not considering what happens on a cache miss in each strategy.
Mention read-through as a variant of cache-aside where the cache itself handles DB reads, and discuss which strategies pair well with Redis vs Memcached.
Interview-ready guide
Interview answer
Cache strategies differ in who fills the cache and when — and choosing the wrong strategy leads to either stale data (write-behind) or cache misses at the worst time (cache-aside on cold start).
Cache-aside (lazy loading) — the most common
- The application checks the cache first; on a miss, it queries the database, stores the result in the cache, and returns it — which means the cache only holds data that's been requested, so cold start doesn't pre-populate anything
- This is the right default for most read-heavy workloads: simple to implement, no wasted cache space on data that's never read
- The risk is cache stampede on cold start or after expiry: many concurrent requests all miss simultaneously, all hit the database, and all try to write the same key — handled with probabilistic early expiry or a mutex
Write-through — always update cache on write
- The application writes to the cache and the database together — which means the cache is always warm and reads are always fast, but writes are slower (two writes instead of one) and cache entries exist even for data that's never read
- Best when you can't afford a cache miss for any user — payment processing, real-time inventory, user session data
Write-behind (write-back) — write to cache first, database later
- Writes go to the cache immediately and the database asynchronously in the background — which means writes are extremely fast but the database may be temporarily behind, and a Redis crash before the async flush loses those writes
- Only appropriate for high-throughput write scenarios where some data loss is acceptable: analytics counters, activity feeds, approximate metrics
Read-through — the cache fetches from the database itself
- The application always reads from the cache; on a miss, the cache automatically queries the database and populates itself — the application code doesn't handle misses explicitly; used in Redis caching middleware like AWS ElastiCache with DAX
Cache-Aside vs Write-Through vs Write-Behind Caching Strategies
Direct Answer
Cache-aside (lazy loading) puts cache management in application code: read from cache, fall back to DB on miss, then populate the cache. Write-through keeps cache and DB always in sync by writing to both on every update, at the cost of write latency. Write-behind (write-back) writes to the cache immediately and asynchronously flushes to the DB, boosting write throughput but risking data loss on crash. The right choice depends on your read/write ratio and tolerance for stale data or data loss.
Code Example
The cache-aside pattern in Java with Spring and Redis:
@Service
public class ProductService {
private final ProductRepository repo;
private final RedisTemplate<String, Product> redis;
// Cache-aside READ: check cache, fallback to DB, populate cache
public Product findById(Long id) {
String key = "product:" + id;
Product cached = redis.opsForValue().get(key);
if (cached != null) {
return cached; // Cache hit — skip the DB entirely
}
// Cache miss — load from database
Product product = repo.findById(id)
.orElseThrow(() -> new ProductNotFoundException(id));
// Populate cache with TTL so stale entries auto-expire
redis.opsForValue().set(key, product, Duration.ofMinutes(15));
return product;
}
// Cache-aside WRITE: update DB first, then evict stale cache
public Product update(Product product) {
Product saved = repo.save(product);
redis.delete("product:" + saved.getId()); // Evict, don't update
return saved;
}
}
Why evict instead of update on write? Eviction is simpler and avoids race conditions where a concurrent read between the DB write and cache update could re-populate the cache with stale data. The next read will miss the cache and fetch the fresh value from the DB.
With Spring annotations, the same pattern becomes declarative:
@Cacheable("products") // Cache-aside read
public Product findById(Long id) { return repo.findById(id).orElseThrow(); }
@CacheEvict("products") // Evict on write
public void update(Product p) { repo.save(p); }
Common Mistakes & Pitfalls
Confusing write-through with write-behind, or not considering what happens on a cache miss in each strategy.
Check your understanding
Answer these without looking back at the article.
- How does read-through caching differ from cache-aside?
- What is the refresh-ahead pattern and when would you use it?
- How would you handle a write-behind cache failure before the async flush completes?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.