Caching

Lesson 4 of 14 · 22 min

x
29%

Eviction Policies: LRU, LFU, FIFO & TTL

Cache memory is finite. When the cache is full and a new entry arrives, something must be removed — that decision is the eviction policy. The right policy depends on your access patterns. LRU (Least Recently Used) evicts the entry that has not been accessed for the longest time. It works well for most workloads because recently used data tends to be used again — temporal locality. LFU (Least Frequently Used) evicts the entry with the fewest accesses over its lifetime, better when some items are consistently popular. FIFO evicts the oldest inserted entry regardless of usage — simple but often suboptimal. Random eviction picks any entry arbitrarily; surprisingly effective and zero bookkeeping overhead. TTL (time-to-live) expiry removes entries after a fixed duration regardless of usage — essential for data that becomes stale on a schedule.

Before
No eviction — cache grows until OOM
const cache = new Map();

function set(key, value) {
  cache.set(key, value);  // never removes anything
}
// Memory usage grows forever until the process crashes
After
LRU with max capacity
class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.cache = new Map(); // Map preserves insertion order
  }

  get(key) {
    if (!this.cache.has(key)) return null;
    const val = this.cache.get(key);
    this.cache.delete(key);
    this.cache.set(key, val); // move to end (most recent)
    return val;
  }

  set(key, value) {
    if (this.cache.has(key)) this.cache.delete(key);
    else if (this.cache.size >= this.capacity) {
      const oldest = this.cache.keys().next().value;
      this.cache.delete(oldest); // evict LRU
    }
    this.cache.set(key, value);
  }
}

Key Takeaway

LRU is the default choice for most caches — combine it with TTL when data has a natural freshness window.

PreviousNext Lesson