No policy wins everywhere
Hit ratio for every policy on every workload, at the cache size chosen above. Color shows the gain or loss against plain LRU. Pick a column to explore that workload below.
Hit ratio by policy and workload
Inside one workload
What the requests look like
Hit ratio as the cache grows
Log scale. Click to set the cache size.
Hit ratio over time
Per 2,000 requests, starting from an empty cache.
Hit ratio is only half the bill
What each policy does on every request decides how it behaves under many threads. A policy that rewrites a shared list on every hit needs a lock on every request. One that only flips a bit or bumps a small counter can serve hits without coordinating. The measured columns come from the same simulation, for the workload and size chosen above.
How each policy decides
What each policy bets on, and where the simulation above shows the bet losing.
How this works
- Every number on this page is computed in your browser by sim.js, in a background worker: 5 workloads × 13 cache sizes × 9 policies, each replaying the same 200,000-request trace. Changing the skew re-runs the three Zipf-based workloads.
- The catalog has 8,000 keys. Scans and fresh content add new keys on top. Hit ratio counts every request, including the first request for each key, which no policy can hit. The cache starts empty.
- Implementations follow the original papers. S3-FIFO uses a 10% small queue and a ghost queue the size of the main queue. W-TinyLFU uses a 1% window, an 80/20 segmented main area and a 4-bit count-min sketch that halves every 10× capacity requests. Caffeine also resizes the window on the fly, which this simulation does not. CLOCK inserts new keys with the reference bit cleared.
- “Requests that take the lock” counts requests that relink a shared list or reorder a heap. Production caches soften this with sampling, striping or buffered updates (Caffeine batches reads in ring buffers), so read it as the policy's inherent cost, not a benchmark.
- Workloads are synthetic and seeded, so the same settings always give the same result. Real traces are messier. Treat this as intuition for which assumptions each policy makes, not as a ranking.