In this lesson, you will learn how to maintain stable memory usage in your Node.js applications by automatically discarding the oldest, least accessed data using an LRU (Least Recently Used) eviction policy.
The Problem: Memory Bloat
When caching data in memory, your cache size can grow indefinitely until the Node.js process crashes with an OutOfMemory error. Simply setting a TTL (Time-To-Live) helps, but it doesn't account for popularity—a heavily used item might be evicted just because its timer expired, while a stale, unused item might stay in memory.
The LRU Strategy
An LRU policy treats your cache like a chronological queue. Every time you access an item, you move it to the "front" of the queue. When the cache reaches its maximum allowed capacity, you evict the item at the very "back"—the one that hasn't been accessed for the longest time.
Implementation Logic
In Node.js, the most efficient way to track this order is using a Map. Because a JavaScript Map preserves the order of key insertion, we can combine it with a simple "delete and re-insert" trick to maintain the "most recent" position.
class LRUCache {
constructor(limit) {
this.limit = limit;
this.cache = new Map();
}
get(key) {
if (!this.cache.has(key)) return null;
// Refresh access: move to "most recently used"
const value = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, value);
return value;
}
set(key, value) {
if (this.cache.has(key)) this.cache.delete(key);
else if (this.cache.size >= this.limit) {
// Evict the oldest (the first item in the map)
const oldestKey = this.cache.keys().next().value;
this.cache.delete(oldestKey);
}
this.cache.set(key, value);
}
}
By deleting and re-inserting the item upon access, the Map iterator always maintains the order: the oldest entries are at the beginning (.keys().next()), and the freshest are at the end. This keeps your memory footprint constant regardless of how many items are added over time.
Key Takeaway: By combining access-tracking with a fixed-size limit, an LRU policy ensures your memory is always reserved for the most relevant data while preventing unbounded heap growth.