The MQ Cache Eviction Pattern: Multi-Queue LRU for Database Buffer Pools

2026-07-19

You've seen LRU, 2Q, ARC, and LIRS. The Multi-Queue (MQ) algorithm is what actually ships in production database buffer managers and second-level storage caches. It was designed at IBM specifically for the workload nobody else optimizes for: second-level buffer caches, where the first-level cache has already absorbed all the temporal locality and what's left is a nearly-random access pattern with a long tail of frequency.

The setup. MQ maintains m LRU queues, numbered Q0 through Q(m-1), plus a history buffer Qout that stores metadata (no data) for evicted blocks. Each block carries a reference count. When accessed:

Why this beats LRU/2Q for buffer pools. A first-level cache (say, PostgreSQL's shared_buffers) has already served the "hot again in the last 10ms" reads. What hits the OS page cache or SAN cache below is dominated by scans and infrequent-but-recurring blocks. LRU treats a one-time full-table scan the same as your hot index root page and evicts the index. MQ's frequency-aware queues protect that index page in Q3 or Q4 while the scan traffic churns through Q0.

Concrete numbers. The original 2001 paper measured a 5-second Oracle TPC-C trace against a second-level cache. At 512MB, LRU hit rate was ~30%; MQ hit ~45% — a 50% reduction in misses, which for a spinning-disk backend translated to roughly 40% lower average query latency. Even against modern SSDs, halving misses halves the tail latency that dominates p99.

Rule of thumb for tuning. Set m = 8 queues (log2 of expected max refcount) and lifetime ≈ working-set size in blocks. Size Qout to hold metadata for roughly one cache's worth of recently-evicted blocks (~50 bytes each, so cheap). If your workload is first-level (application-facing), stick with ARC or W-TinyLFU — MQ's advantage disappears when temporal locality is still intact.

When to reach for it. You're building the second cache in a stack: an SSD tier under RAM, a shared storage cache under per-node caches, or a CDN origin shield. Anywhere the layer above has filtered out short-term reuse.

See it in action: Check out Redis in 100 Seconds by Fireship to see this theory applied.
Key Takeaway: Multi-Queue LRU wins in second-level caches by using frequency-banded queues plus a metadata ghost list, protecting rarely-but-repeatedly-accessed blocks from scan traffic that LRU would let flush them.

All newsletters