Skip to content
About
Main content

Size a cache

The decision

You need to decide how big a should be, or whether adding capacity or a new tier will help. is not a knob you turn up; it is a property of the workload, which you measure. How much cache does this workload need, and what will it not fix?

You will end with a cache size and tier layout justified by measurements, and a list of what the cache cannot fix.


Work through it

1

Measure reuse distance, not time

For each access, count the distinct other items accessed since the previous access to the same item: its . Under an access hits exactly when its reuse distance is smaller than the cache, so one histogram gives . Sample by hashing keys (keep a fixed share of keys), never by time window. If you cannot instrument it: count distinct items per window and fit how popularity falls with rank.

2

Find out whether the cache must grow with the data

Fit the popularity exponent α: how steeply request share falls from the most popular item to the next. Above 1: the size needed for a given hit rate does not depend on how much data you have. At 1 or below (typical for web objects and analytic query shapes, 0.6–0.8): a fixed cache over growing data loses hit rate silently; budget for growth, or document the decay. At α = 0.8, a 90% hit rate needs cached, which is replication, not caching.

3

Split the traffic into its three streams

Separate items that stay popular, items hot for a while (a session, a job's ), and items touched once (scans, backfills). If the touched-once share is large: you need admission control that refuses those items, not a bigger cache. One scan larger than the cache evicts everything useful.

4

Size to just past a knee

have plateaus, where more capacity returns nothing, and cliffs, where a little more captures a whole working set. Land just past a cliff, never on a plateau. Do not believe "we doubled it and nothing happened" until you have looked at where on the curve you were. For a shared cache: split capacity so each tenant's miss ratio falls equally fast per extra gigabyte.

5

Check that each tier pays

A new tier helps only if its hit rate beats its relative to the tier below: hit rate > its lookup time ÷ the lower tier's time. A tier 10× faster needs over 10%; local NVMe over needs only 0.2%. Run the money version separately: with per-request storage pricing, an SSD tier over object storage pays at hit rates latency alone would not justify.

6

For derived objects, count every input's writes

A cached result or view is worth keeping only if . Reads per version is read rate ÷ invalidating writes, and for an object built from many inputs the writes are the sum over all of them. Many inputs is what usually fails this.

7

Decide whether the store below survives the cache failing

At hit rate h, the store sees only a share (1 − h) of the load, so the cache gives : 20 to 1 at 95%, 100 to 1 at 99%, and a one-point drop at 99% doubles the store's load. If the store cannot survive the cache being empty: the cache is a dependency, not an optimization. Plan for restarts: a warm-up ramp, or a cache that survives the process restarting.

8

Check the percentile you promised

A cache with hit rate h leaves every above h exactly where it was: at 95% it cannot improve p95 or p99. If the promise is p99 and the hit rate is below 99%: caching is the wrong instrument. Shrink the miss cost instead (another tier), send a duplicate request to a second replica after a short wait (hedging), or shed load. Cache in front of the slowest thing, not the most-requested one: .