Responsive Node.js Endpoint Under High Concurrency
Note from the N-iX interview prep ā backend performance.
Summary: Use non-blocking async patterns, offload CPU tasks, and scale horizontally.
Key strategies
- Non-blocking Async I/O:
- Use
async/awaitfor all I/O (DB, external APIs, file system). - Avoid
Syncfunctions (readFileSync,crypto.pbkdf2Sync). - Use streams for large data (CSV exports) to avoid buffering in memory.
- Use
- CPU-intensive tasks:
- Move them to Worker Threads or a separate microservice.
- Use
worker_threadsor an external job queue (Bull + Redis). - Respond immediately with
202 Acceptedand process in the background.
- Connection Pooling:
- For PostgreSQL, use
pg.Poolwith a configured max connections. - Keep the pool size below the DBās max to avoid timeouts.
- For PostgreSQL, use
- Rate Limiting & Backpressure:
- Apply rate limiting (per IP/user) ā see middleware order.
- Use backpressure signals to slow down clients when overloaded.
- Horizontal scaling:
- Run multiple Node instances (cluster mode or PM2).
- Use a load balancer (NGINX) to distribute requests.
- Ensure statelessness so any instance can handle any request.
- Monitoring & Observability:
- Metrics (req/sec, error rate, latency) via Prometheus.
- Distributed tracing (OpenTelemetry) to pinpoint bottlenecks.
app.post("/api/report", async (req, res) => {
const { data } = req.body;
const job = await queue.add("generate-report", { data });
res.status(202).json({ jobId: job.id }); // immediate response
});
Real-world result (Seguralta)
Used for monthly commission reports. The endpoint handled 2,500 concurrent
requests without blocking the event loop, with average response time < 200ms for
the initial 202 Accepted.
Related: middleware chain Ā· index.