skip to content
logo
Table of Contents

Understanding Memory Usage in Node.js

Node.js applications rely on V8’s heap, which includes:

  • Old Space – Long-lived objects
  • New Space – Short-lived objects
  • Large Object Space – Objects too big for regular allocation

This post covers profiling memory usage, detecting leaks, and optimizing garbage collection.


Analyzing Memory Usage

Check Heap Statistics

console.log(process.memoryUsage());

Monitor Memory in Real Time

setInterval(() => {
const usage = process.memoryUsage();
console.log(`Heap Used: ${usage.heapUsed / 1024 / 1024} MB`);
}, 5000);

Identifying Memory Leaks

Common causes:

  1. Unreleased event listeners
  2. Caching objects without limits
  3. Global variables accumulating references

Example: Leaking Event Listeners

import EventEmitter from "events";
const emitter = new EventEmitter();
setInterval(() => {
emitter.on("data", () => {}); // Causes memory leak
}, 1000);

Fix: Remove Listeners

emitter.removeAllListeners("data");

Garbage Collection Optimization

Force a Manual Garbage Collection

global.gc(); // Requires running Node with --expose-gc

Run with:

Terminal window
node --expose-gc app.js

Adjust Garbage Collector Settings

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

Avoid Large Memory Consumption

Use Streams for Large Data

Avoid loading entire files into memory.

import fs from "fs";
const readStream = fs.createReadStream("large-file.txt");
readStream.on("data", (chunk) => console.log(`Received ${chunk.length} bytes`));

Profiling with Chrome DevTools

Run Node with:

Terminal window
node --inspect app.js

Go to chrome://inspect, select your process, and analyze heap snapshots.


Conclusion

  • Monitor heap usage and avoid leaks.
  • Use event listener cleanup.
  • Optimize garbage collection settings.
  • Use streams instead of in-memory buffers.

Memory efficiency improves performance and scalability, ensuring Node.js apps stay fast under load.