Performance, Memory, and Profiling
Diagnose slow Node.js applications, understand memory usage, identify event-loop blocking, optimize database access, and use profiling tools.
Avoiding Event-Loop Blocking
Node.js performance depends heavily on keeping the event loop responsive. Expensive synchronous operations, huge JSON parsing or serialization, inefficient regular expressions, and CPU-heavy algorithms can delay unrelated requests.
Performance optimization should begin with measurement rather than assumptions.
app.get('/report', async (req, res) => {
const report = await generateReportInWorker(req.query.id);
res.json(report);
});- Keep request handlers lightweight when possible.
- Move expensive CPU work to workers or background processes.
- Measure event-loop latency to detect blocking workloads.
What is a common cause of poor Node.js concurrency?
Memory Management and Garbage Collection
Node.js uses V8's garbage collector to reclaim memory that is no longer reachable. Memory leaks occur when application references unintentionally keep objects alive.
Common causes include unbounded caches, global collections, event listeners that are never removed, timers that remain active, and closures retaining large objects.
Garbage collection cannot reclaim objects that are still reachable. Look for references that live longer than the data they retain.
const cache = new Map();
function setUser(id, user) {
cache.set(id, user);
}
// Production code should define an eviction or expiration strategy.- Garbage collection removes unreachable objects.
- Unbounded collections are a common source of memory growth.
- Heap snapshots can help identify retained objects.
Why can an unbounded Map cause memory growth?
Profiling and Performance Optimization
Node.js applications can be profiled using tools such as the Node inspector, CPU profiles, heap snapshots, and performance APIs. Production performance work should examine real bottlenecks such as database queries, network calls, serialization, event-loop delay, and memory pressure.
Useful optimizations include database indexing, batching, pagination, connection pooling, caching, stream processing, and algorithmic improvements.
- Profile before optimizing.
- Database and network latency are often more significant than JavaScript micro-optimizations.
- Measure latency distributions such as p50, p95, and p99 rather than only averages.
What is usually the best first step before a performance optimization?