Cache-Aside Pattern

In cache-aside, the application checks the cache first and loads a missing value from the source before caching it. The source remains authoritative, so updates, expiration, and concurrent misses need deliberate handling.

In cache-aside, the application owns the read path: it checks the cache first and returns a cached value when present. On a miss, it fetches the value from the authoritative data source, puts that value into the cache, and returns it.

The cache is not automatically kept in sync with the source. When data changes, the application commonly updates the source and then invalidates the corresponding cache entry, or updates both in a carefully designed sequence. A later read can repopulate an invalidated entry.

Cache-aside is straightforward and lets applications cache only the data they actually request. It is useful when the source remains authoritative and the cache may be lost or cleared without losing the underlying data.

The pattern introduces consistency and concurrency questions. A cache entry can be stale until it expires or is invalidated, and simultaneous misses for the same key may cause multiple source reads. TTLs, invalidation policies, request coalescing, or locks can address these issues depending on the system's needs.

Key points

Interview questions

Walk through a cache-aside read for a key that is not cached.

The application first looks for the requested key in the cache. If the key exists, it returns that value; otherwise it reads from the authoritative source, stores the result in the cache, and returns it. This keeps the cache populated on demand rather than loading every possible value in advance.

How would you handle updates to data stored in a cache-aside system?

The source should normally be updated first, followed by invalidation of the affected cache entry. This avoids treating the cache as the authoritative store and lets the next read fetch the updated value. There can still be a brief race between the source update and invalidation, so the exact ordering and guarantees should be chosen for the system's consistency needs.

What is a cache stampede, and how can cache-aside systems reduce its impact?

If many requests miss the same key at once, each may independently query the source before any request fills the cache. This is a cache stampede, and it can amplify load on an already busy backend. Possible mitigations include coalescing concurrent loads by key, using a lock, adding randomized expiration times, or serving a briefly stale value where that is acceptable.

When would you choose cache-aside, and what operational risks would you assess?

Cache-aside is a good fit when the application can tolerate bounded staleness and wants to load data only when requested. It is less suitable when every read must observe the latest write, unless additional consistency mechanisms are added. I would evaluate access patterns, invalidation reliability, source load during misses, and the consequences of serving stale data before choosing it.