Tracing Memory Bloat in Node.js Services Using Heap Snapshots
Your Node.js service starts fresh at 120 MB and sits at 900 MB four hours later β without a corresponding spike in traffic. Restarting it buys time, but the leak comes back. Heap snapshots give you a concrete picture of what objects are alive in memory and what's refusing to let go.
This guide walks you through capturing snapshots, comparing them across time, and reading the results to find the code responsible.
What you'll learn
- How the V8 heap is structured and why objects accumulate
- How to capture heap snapshots using the built-in
v8module and Chrome DevTools - How to compare two snapshots to isolate newly retained objects
- How to read a snapshot's retainer chain to find the root cause
- Patterns that most commonly cause leaks in production Node.js services
Prerequisites
You'll need Node.js 14 or later (the v8 module's writeHeapSnapshot API is stable from v11.13). You should be comfortable reading a stack trace and have basic familiarity with how JavaScript closures work. Chrome or Edge (any Chromium browser) is enough for the DevTools viewer.
How V8 Manages Memory
V8 divides heap memory into two main spaces: the new space (for short-lived objects that get collected frequently) and the old space (for objects that survive long enough to be promoted). A leak happens when objects that should be short-lived get promoted to old space and are never collected because something still holds a reference to them.
The garbage collector can only free an object when no live root β a global variable, an active closure, a running event listener β holds a reference chain to it. Finding leaks means finding that unexpected reference chain.
Taking a Heap Snapshot
The simplest approach is to write a snapshot directly from your process using the built-in v8 module.
π€ Share this article
Sign in to save
Related Articles
Comments (0)
No comments yet. Be the first!
Leave a Comment