Skip to main content

Refresh-Ahead Cache

Refresh-ahead caching proactively reloads hot entries before they expire so popular keys never incur miss latency. It suits predictable hot keys with expensive backing loads, at the cost of slight staleness.

Type
Data
When to Use
Predictable Hot Keys, Low Latency Reads, Expensive Backing Load

A refresh-ahead cache anticipates expiry. For frequently accessed entries it triggers an asynchronous reload from the backing store before the TTL lapses, so the next read still hits a warm, fresh value instead of paying the cost of a miss. It targets the worst case of read-through caching: latency spikes when a hot key expires under load.

How It Works

Each entry has a TTL and a refresh-ahead factor (for example, 0.75). When a read arrives after 75% of the TTL has elapsed, the cache returns the current value immediately and schedules an asynchronous reload in the background. The reload replaces the entry and resets its TTL. Only keys that are actually being read get refreshed, so cold keys still expire naturally and do not waste backing-store calls.

Implementations (Coherence, Ehcache, Caffeine's refreshAfterWrite) typically refresh a key at most once per window and serve the stale-but-valid value during the reload, avoiding both miss latency and a thundering herd.

When to Use It

Use refresh-ahead when a small set of hot keys is read constantly, the backing load is expensive, and even occasional miss latency is unacceptable: pricing, feature configuration, exchange rates, and home-page content. It shines where access is predictable enough that "recently read" reliably predicts "about to be read again."

Trade-offs

Refresh-ahead serves slightly stale data during the refresh window, so it is unsuitable when reads must reflect the absolute latest write. It adds background load even for keys that might not be read again immediately, and the refresh factor needs tuning: too eager wastes backing calls, too late reintroduces miss spikes. It also adds implementation complexity over plain read-through and only helps keys that are read regularly; sporadically accessed keys see no benefit.

Related Patterns

Refresh-ahead is an enhancement to read-through-cache and is often combined with write-through-cache so writes also keep entries warm. Cache-aside is the simpler manual alternative when proactive refresh is not worth the complexity.

Example

A currency service caches exchange rates with a 60-second TTL and a 0.8 refresh factor. Because the conversion endpoint is queried thousands of times per second, every hot rate is reloaded in the background around the 48-second mark. Clients always read from a warm cache, never observe the 200 ms upstream call, and rates stay within a minute of freshness.