Performance
Keep Node fast by not blocking the event loop.
Node is fast for I/O, but its single thread means one rule dominates: never block the event loop. A slow synchronous operation freezes every request at once.
Tips
- Prefer asynchronous APIs over their
Syncversions in servers. - Offload heavy CPU work to worker threads or a separate service.
- Cache results you compute repeatedly.
- Stream large data instead of buffering it all.
Example
// BAD: blocks the event loop for everyone
const data = fs.readFileSync('huge.json');
// GOOD: non-blocking, other requests keep flowing
fs.readFile('huge.json', (err, data) => {
if (err) throw err;
console.log('Loaded without blocking');
});When to use it
- A developer profiles an Express API with `--prof` and discovers a JSON serialization function consuming 60% of CPU, then replaces it with `fast-json-stringify`.
- A service routes CPU-intensive report generation to Worker Threads so the main event loop stays free to handle incoming HTTP requests.
- A caching layer wraps database queries with an in-memory LRU cache so repeated identical requests are served in microseconds instead of milliseconds.
More examples
Measure execution time
Uses `perf_hooks.performance.now()` for high-resolution timing of a code block.
const { performance } = require('perf_hooks');
const t0 = performance.now();
// ... work ...
for (let i = 0; i < 1e6; i++) Math.sqrt(i);
const t1 = performance.now();
console.log(`Took ${(t1 - t0).toFixed(2)} ms`);Cache expensive results in memory
Caches the result of an expensive database call in a `Map` to avoid repeated slow queries for the same input.
const cache = new Map();
async function getReport(id) {
if (cache.has(id)) return cache.get(id);
const data = await db.fetchReport(id); // slow
cache.set(id, data);
return data;
}
// Optional: evict after 60s
setInterval(() => cache.clear(), 60_000);Generate a CPU profile
Uses Node's built-in V8 profiler to record CPU ticks and `--prof-process` to produce a readable summary.
# Run with V8 profiler
node --prof server.js
# After a workload, Ctrl+C to write isolate-*.log
# Process the log into readable text:
node --prof-process isolate-*.log > profile.txt
# Look for 'ticks' to find hot functions
Discussion