Skip to content
EdgeServers
Blog

The Node.js memory leak playbook — heap snapshots, clinic.js, and the four patterns we keep finding

May 21, 2026 · 1 min read · by Sudhanshu K.

Node.js memory leaks tend to look terrifying and usually aren't. The same four patterns appear in audit after audit: a Map/Set that grows unbounded, a closure that retains an unexpectedly large parent scope, event listeners attached but never removed, and an in-process cache without an eviction policy.

This is the diagnosis playbook we run on customer Node services that start eating memory week-on-week.

Heap snapshots — the only diagnosis that's not guesswork

import v8 from 'node:v8';
import fs from 'node:fs';
 
process.on('SIGUSR2', () => {
  const file = `/tmp/heap-${Date.now()}.heapsnapshot`;
  v8.writeHeapSnapshot(file);
  console.log('wrote', file);
});

Send SIGUSR2 to the process, get a snapshot, repeat after 30 minutes of traffic, diff the two in Chrome DevTools' Memory tab. The retained-objects column tells you exactly what's growing.

The full write-up covers:

  • The four patterns and how each shows up in the heap snapshot diff
  • clinic.js doctor and clinic flame for CPU + memory together
  • --inspect and Chrome DevTools for live profiling in non-production
  • Running the leak detection against your own services in CI before production
  • The cgroups + OOMKiller reading when the leak shipped anyway
  • When the "leak" is actually V8's young generation not collecting fast enough (it isn't a leak)

Reach out if your Node service has been quietly growing and nobody's sure why.

Full article available

Read the full article