In this lesson, you will learn how to quantify the impact of major and minor Garbage Collection (GC) cycles on your application's request response times.
As you have learned in previous lessons, V8 divides its heap into specific generations. A "minor" GC (Scavenge) quickly collects short-lived objects in the Young Generation, while a "major" GC (Mark-Sweep-Compact) handles the Old Generation. Because these operations are "stop-the-world" events, they pause your JavaScript execution, directly inflating your request latency.
To measure this, we use the perf_hooks module to observe the PerformanceObserver for gc entry types. By correlating these events with your incoming HTTP requests, you can calculate the "GC tax" paid by specific transactions.
Quantifying the Latency Gap
When a request comes in, it triggers object allocations. If a GC cycle occurs during that request's lifecycle, the duration of the request will increase by the exact duration of the GC pause. You can capture this by measuring the time spent in GC during a specific request window:
const { PerformanceObserver } = require('perf_hooks');
let activeGcPause = 0;
const obs = new PerformanceObserver((list) => {
const entry = list.getEntries()[0];
activeGcPause += entry.duration; // Total time spent in this GC cycle
});
obs.observe({ entryTypes: ['gc'] });
// Middleware to track latency
app.use((req, res, next) => {
const startGc = activeGcPause;
res.on('finish', () => {
const gcImpact = activeGcPause - startGc;
if (gcImpact > 50) {
console.warn(`Request delayed by ${gcImpact}ms due to GC`);
}
});
next();
});
Distinguishing Minor vs. Major
Minor GC cycles are frequent but extremely fast (often < 1ms), usually having a negligible impact on throughput. Major GC cycles, however, grow in duration as the heap reaches its limit. By inspecting the kind property in the performance entry (where 1 is Scavenge and 2 is Mark-Sweep), you can identify if your latency spikes are caused by routine cleanups or expensive heap-wide compaction. High latency in Major GC often signals that your heap is too small for your workload, leading to overly frequent full collections.
Key Takeaway: To optimize response times, correlate GC pause durations with request metrics to determine if latency spikes are caused by routine minor collections or disruptive major heap cleanups.