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:
min(log2(refcount), m-1) — hotter blocks live in higher queues.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.
