█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Programming Languages/Node.js/Node.js in Production
45 minIntermediate

Node.js in Production

After this lesson, you will be able to: Run Node in production: process managers (PM2), clustering, memory profiling, graceful shutdown.

Node app + production = these four concerns. Without them you ship hot-mess infra.

Prerequisites:WebSockets

Process managers + clustering

PM2: classic process manager. Restart on crash, log rotation, multiple instances per core. Node's cluster module: built-in multi-process fork (one per CPU). Modern hosts (Docker, Kubernetes, Fargate, Vercel Functions) handle process management themselves, PM2 becomes optional. Default in 2026: one Node process per container, host orchestrator handles scaling.

Graceful shutdown (the must-have)

Without this, deploys drop in-flight requests.

python
import { createServer } from "node:http";
import express from "express";
const app = express();
const server = createServer(app);
server.listen(3000);
let shuttingDown = false;
app.get("/health", (_req, res) => {
res.status(shuttingDown ? 503 : 200).json({ ok: !shuttingDown });
});
async function shutdown() {
if (shuttingDown) return;
shuttingDown = true;
console.log("draining...");
server.close(() => {
console.log("closed");
process.exit(0);
});
setTimeout(() => process.exit(1), 30_000); // hard exit after 30s
}
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);

Memory + profiling

Memory leaks: usually long-lived listeners not removed; closures holding references; unbounded caches. Tools: `--inspect` flag → Chrome DevTools → Memory + Performance tabs. Heap snapshots: `process.kill -SIGUSR2 <pid>` (with --heap-prof or third-party tools). Production: monitor RSS + heap via process.memoryUsage(); alert on growth trend.

Health checks + observability

Every prod app needs these.

python
// Health endpoint (load balancer probes this)
app.get("/health", async (_req, res) => {
try {
await db.$queryRaw`SELECT 1`;
res.json({ ok: true });
} catch (e) {
res.status(503).json({ ok: false, error: "db" });
}
});
// Request logging (pino is the standard)
import pino from "pino";
const log = pino({ level: process.env.LOG_LEVEL ?? "info" });
app.use((req, _res, next) => {
log.info({ method: req.method, url: req.url }, "req");
next();
});
// Metrics: prom-client for Prometheus, OpenTelemetry for traces.

Common mistakes only experienced backend devs avoid

No SIGTERM handler. Deploys drop connections. console.log everywhere. Use pino (structured JSON). Trusting /health that returns 200 when DB is down. Check downstream dependencies. Unbounded in-memory caches. Heap grows forever.

Quick Check

Why is `process.on('SIGTERM', shutdown)` critical?

Pick the cleanest answer.

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←WebSockets and Real-Time
Back to Node.js
Testing Node.js→