Debugging & Profiling Node

Debugging is finding and fixing why your code misbehaves, and profiling is measuring where it spends time and memory — Node gives you the inspector, the debugger keyword, console timers, and CPU and heap profilers to do both.

Learn Debugging & Profiling Node in our free Node.js course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Node.js course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll measure code with console.time , read memory with process.memoryUsage() , set breakpoints with --inspect and the debugger keyword, profile CPU with --prof and clinic.js, and hunt memory leaks with heap snapshots.

What You'll Learn in This Lesson

1️⃣ Timing Code with console.time

The fastest way to measure a block is a pair of timers. console.time('label') starts a stopwatch and console.timeEnd('label') stops it and prints the elapsed time. Use the same label for both. It's zero-setup and perfect for confirming whether a suspected hotspot is actually slow.

2️⃣ Reading Memory Usage

process.memoryUsage() returns an object of byte counts. The two you watch most are rss (total resident memory) and heapUsed (live JavaScript objects). Sampling it before and after work shows how much an operation costs. Watching heapUsed climb without falling is the classic signature of a memory leak.

3️⃣ The Inspector, Breakpoints & Profilers

For real debugging, start your app with node --inspect app.js and open chrome://inspect to get full DevTools — breakpoints, stepping, variable inspection. The debugger keyword drops a breakpoint right in your code. For performance, node --prof (or clinic.js ) profiles CPU, and the Memory tab's heap snapshots reveal leaks.

Your turn. The timer below works once you fill in the single blank marked ___ . Follow the 👉 hint, then run it (your exact ms will differ, but the value won't).

No blanks — just a brief and an outline. Use two labeled timers to compare string concatenation versus array-join for building a big string. Build it, run it, and see which wins on your machine (the exact times vary).

📋 Quick Reference — Debug & Profile

Practice quiz

What does console.time('x') paired with console.timeEnd('x') measure?

  • How much memory a block uses
  • How long the block between them takes to run
  • How many times a function is called
  • The CPU temperature

Answer: How long the block between them takes to run. console.time/timeEnd start and stop a stopwatch for the code between them and print the elapsed time.

Why must console.time and console.timeEnd use the same label?

  • Labels are optional and ignored
  • Mismatched labels print a warning and no timing
  • The label sets the units to ms
  • Different labels run the timer twice as fast

Answer: Mismatched labels print a warning and no timing. timeEnd must match the label given to time; a mismatch prints a warning and no duration.

What units does process.memoryUsage() report values in?

  • Megabytes
  • Kilobytes
  • Bytes
  • Gigabytes

Answer: Bytes. All values are in bytes; divide by 1024*1024 to convert to megabytes.

Which field of process.memoryUsage() tracks live JavaScript objects?

  • heapUsed
  • rss
  • external
  • arrayBuffers

Answer: heapUsed. heapUsed is the size of live JS objects; rss is total resident memory.

How do you start an app with the inspector so you can use Chrome DevTools?

  • node --debug app.js
  • node --profile app.js
  • node --watch app.js
  • node --inspect app.js

Answer: node --inspect app.js. node --inspect app.js enables the inspector; open chrome://inspect to attach DevTools.

What does the debugger keyword do when run under an inspector?

  • It prints the call stack to the console
  • It pauses execution at that line as a breakpoint
  • It restarts the program
  • It disables all other breakpoints

Answer: It pauses execution at that line as a breakpoint. The debugger statement is an inline breakpoint that pauses execution when an inspector is attached.

Which command does CPU profiling to find slow functions?

  • node --mem app.js
  • node --prof app.js
  • node --trace app.js
  • node --slow app.js

Answer: node --prof app.js. node --prof writes an isolate log you process into a profile that shows where CPU time goes.

What is the classic signature of a memory leak?

  • heapUsed that climbs over time and never comes back down
  • A single spike that the GC reclaims
  • Constant memory that never changes
  • CPU usage at 100 percent

Answer: heapUsed that climbs over time and never comes back down. A leak shows as retained memory that keeps growing and is never reclaimed, risking an out-of-memory crash.

When should you reach for a profiler instead of console.time?

  • When you already know the exact slow line
  • When you don't yet know where the time goes across the whole program
  • When you only need to format output
  • When the program has no functions

Answer: When you don't yet know where the time goes across the whole program. Use console.time to confirm a known hotspot; use a profiler to discover an unknown one across the whole app.

How do you compare two heap snapshots to find a leak in Chrome DevTools?

  • Run --prof-process twice
  • Use console.memory() before and after
  • Take a snapshot, do work, take another, and see which object types grew
  • Restart the process between reads

Answer: Take a snapshot, do work, take another, and see which object types grew. Two snapshots taken around the suspect workload let the Comparison view reveal which retained objects grew.