Performance Optimization

1. Using Clustering

Example: Cluster module

import cluster from "node:cluster";
import os from "node:os";

if (cluster.isPrimary) {
  for (let i = 0; i < os.availableParallelism(); i++) cluster.fork();
  cluster.on("exit", (worker) => { logger.warn({ pid: worker.process.pid }, "worker died"); cluster.fork(); });
} else {
  await import("./server.js");
}
Note: In containerized deployments, prefer running one Node process per container and let the orchestrator (Kubernetes) handle horizontal scaling.

2. Enabling Gzip Compression

Example: At edge

app.use(compression({ threshold: 1024 }));  // or terminate at Nginx/CDN

3. Implementing Caching Strategies

LayerTool
BrowserCache-Control, ETag
CDN / proxys-maxage, Vary
AppIn-memory LRU, apicache
DistributedRedis, Memcached
DBMaterialized views, query cache

4. Using Connection Pooling

Example: pg Pool

new pg.Pool({ max: 20, idleTimeoutMillis: 30_000 });

5. Optimizing Database Queries

TechniqueNotes
Add indexes on filter/sort columnsUse EXPLAIN ANALYZE to verify
Avoid N+1Use JOIN, include, DataLoader
Select only needed columnsNo SELECT *
Paginate large resultsLimit + cursor
Use prepared statementsRe-use plans, prevent injection

6. Lazy Loading Resources

Example: Dynamic import

app.get("/report", async (req, res) => {
  const { generateReport } = await import("./heavy-report.js");
  res.json(await generateReport(req.query));
});

7. Using CDN for Static Assets

PatternBenefit
Hashed asset URLsLong-cache + safe invalidation
Origin-pull CDNZero-config; cache HEAD/GET only
Push to S3 + CloudFrontDecouple from app server

8. Implementing Response Streaming

Example: ndjson streaming

app.get("/export", async (req, res) => {
  res.type("application/x-ndjson");
  for await (const row of db.cursor()) res.write(JSON.stringify(row) + "\n");
  res.end();
});

9. Minimizing Middleware Stack

Warning: Every app.use() runs on every request. Mount middleware only on the routes that need it.

Example: Scoped middleware

// instead of app.use(heavyMiddleware) globally:
app.use("/admin", heavyMiddleware, adminRouter);

10. Using HTTP/2 with SPDY

Example: Node http2 + Express

// Native http2 + Express requires the http2-express-bridge wrapper, OR
// terminate HTTP/2 at the reverse proxy and forward HTTP/1.1 to Express.
// Recommended: Nginx/Cloudflare HTTP/2 → Express HTTP/1.1
Note: Express does not natively support Node's http2 module. Terminate HTTP/2 at the reverse proxy.

11. Profiling Performance

ToolUse
node --profV8 profiler
clinic.jsDoctor, Flame, Bubbleprof
0xFlame graphs
autocannonHTTP benchmarking
OpenTelemetryDistributed traces

12. Monitoring Memory Usage

Example: Memory metrics

setInterval(() => {
  const m = process.memoryUsage();
  metrics.gauge("rss_bytes").set(m.rss);
  metrics.gauge("heap_used_bytes").set(m.heapUsed);
  metrics.gauge("heap_total_bytes").set(m.heapTotal);
}, 15_000);