Untitled Lesson
Skill Matrix
UNLOCK NODES BY LEARNING NEW TAGS.
What is the key visual difference between a healthy Node.js process's memory usage graph and one with a genuine memory leak?
💻 Code Challenge | +75 XP
Fix a caching function that uses an unbounded Map with no eviction policy, replacing it with a bounded LRU cache that evicts the least-recently-used entry once a max size is reached.
A production service needs to be restarted every few days due to gradually increasing memory usage until it crashes with an out-of-memory error. Reorder the steps to find and fix the leak.
Task: Reorder the blocks in logical sequence to solve the problem.
A.D.A. Interface
Adaptive Didactic Assistant

Pascual Vila
Frontend Instructor // Code Syllabus
The Error //
Implementing an in-memory cache (Map or plain object) with no eviction policy at all
// Wrong: grows forever, effectively a memory leak
const cache = new Map();
// Correct: bounded, evicts least-recently-used entries
import { LRUCache } from "lru-cache";
const cache = new LRUCache({ max: 500 });The Solution //
A cache with no maximum size or expiration policy grows without bound for as long as the process runs, which is functionally a slow-motion memory leak rather than a genuine cache. Use a bounded caching structure (like an LRU cache with a max size) that evicts old entries once a limit is reached.
The Error //
Registering an event listener inside a per-request handler without ever removing it
// Wrong: a new listener added on every request, never removed
app.get("/subscribe", (req, res) => {
emitter.on("update", handler); // accumulates forever
});
// Correct: cleaned up when the connection closes
res.on("close", () => emitter.off("update", handler));The Solution //
Each incoming request that registers a new listener without cleanup accumulates listeners indefinitely — every one of them, along with its entire captured closure, remains in memory for the life of the process, even after the associated request/connection has long since ended.