devnotes.

The V8 Engine, Revisited from the Code Side

We covered what V8 is architecturally back in the Getting Started chapter. This page looks at it from a more practical angle — the actual v8 module Node.js exposes, and what you can do with it.

A quick recap of V8's job

V8 is Google's C++ JavaScript engine — the same one powering Chrome — responsible for taking your JavaScript and turning it into machine code as fast as possible, with automatic memory management (garbage collection) along the way.

Checking memory usage through the v8 module

const v8 = require('v8');

const heapStats = v8.getHeapStatistics();
console.log('Total heap size (MB):', (heapStats.total_heap_size / 1024 / 1024).toFixed(2));
console.log('Used heap size (MB):', (heapStats.used_heap_size / 1024 / 1024).toFixed(2));
console.log('Heap size limit (MB):', (heapStats.heap_size_limit / 1024 / 1024).toFixed(2));

The "heap" is where V8 stores JavaScript objects in memory. Watching used_heap_size climb steadily over time, without ever coming back down, is one of the classic signs of a memory leak — something holding references to objects that should have been garbage-collected long ago.

A simpler, related check through process instead

const used = process.memoryUsage();
console.log(`Heap used: ${(used.heapUsed / 1024 / 1024).toFixed(2)} MB`);
console.log(`RSS (total memory): ${(used.rss / 1024 / 1024).toFixed(2)} MB`);

process.memoryUsage() is the more commonly reached-for tool day to day; the v8 module's stats go deeper when you specifically need to understand heap behavior.

Setting flags V8 itself understands

node --max-old-space-size=4096 app.js

This raises the memory limit V8 allows for its "old space" (long-lived objects) — occasionally necessary for memory-hungry applications that would otherwise hit V8's default ceiling and crash with an out-of-memory error. This isn't something to reach for casually; it's worth first confirming the memory usage is actually legitimate and not a leak that should be fixed instead.

Taking a heap snapshot for deeper investigation

const v8 = require('v8');
const fs = require('fs');

const snapshotStream = v8.getHeapSnapshot();
const fileStream = fs.createWriteStream('heap.heapsnapshot');
snapshotStream.pipe(fileStream);

The resulting .heapsnapshot file can be opened directly in Chrome DevTools' Memory tab, showing exactly what objects are consuming memory and why they're still being held onto — the real tool for chasing down a memory leak once basic monitoring has confirmed one exists.

The practical level most developers need

Most day-to-day Node.js work never touches the v8 module directly — knowing it exists, and reaching for it when memory behavior looks suspicious, is usually enough. The deeper machinery (JIT compilation phases, bytecode, optimization and deoptimization cycles) matters mostly for people working on Node.js's internals or squeezing out extreme performance, not typical application code.

The V8 Engine, Revisited from the Code Side | DevNotes