Fixing the Silent 502 on NestJS: How a Misconfigured PM2 Process on VPS Drained My App’s Traffic in Minutes
It was 2 AM. My NestJS API was humming along, a steady stream of requests from a dozen clients, and the dashboard showed green across the board—until the traffic stopped in under a minute. No alerts, no error logs, just a cold, silent 502 Bad Gateway that left my users hanging and my revenue slipping.
Why This Matters
If you run a production‑grade Node.js service (NestJS, Express, Fastify, you name it) behind a reverse proxy, a single misstep in your process manager can turn a healthy server into a traffic sink. The 502 isn’t just a pesky status code; it’s a signal that the proxy (Nginx, Apache, or Cloudflare) can’t reach your Node process. In the real world that means:
- Lost sales or subscription renewals.
- Higher bounce rates that hurt SEO.
- Customer support tickets that could have been avoided.
In my case, a PM2 ecosystem file was pointing to the wrong script after a recent refactor. The result? PM2 started a ghost process that immediately exited, leaving Nginx with nothing to forward requests to. The fix was simple, but the lesson is huge for any developer who wants to keep uptime high and revenue flowing.
Step‑by‑Step Tutorial: Diagnose & Repair the Silent 502
- Confirm the 502 isn’t a client‑side issue. Open a terminal and
curl -I https://your‑domain.com/api/health. If you seeHTTP/1.1 502 Bad Gateway, the problem is on the server. - Check Nginx (or your reverse proxy) logs. On a VPS this is usually
/var/log/nginx/error.log. Look for lines containing “upstream prematurely closed connection” or “connect() failed”. - Verify your Node process is running. Run
pm2 list. If the app showsstoppedorerrored, you’ve found the culprit. - Inspect the PM2 ecosystem file. A common mistake is an outdated
scriptpath after a rename or a missingnode_modules/.binbinary. Exampleecosystem.config.js:
module.exports = {
apps: [
{
name: "my-nest-app",
script: "./dist/main.js", // ← Ensure this points to the compiled entry file
cwd: "./", // Working directory
instances: "max",
exec_mode: "cluster",
env: {
NODE_ENV: "production",
PORT: 3000
}
}
]
};
- Rebuild and restart. If you renamed
main.tstoapp.ts, rebuild withnpm run buildand thenpm2 restart ecosystem.config.js. - Test the endpoint again. The
curlshould now return200 OK. If it does, hit the web UI to confirm traffic flows. - Persist the fix. Add a health‑check script to your CI pipeline so future merges will fail if the compiled file isn’t where PM2 expects it.
Pro tip: Use pm2 startOrRestart ecosystem.config.js in your deployment script. It will start a fresh process if none exists or gracefully restart the existing one, avoiding the “ghost” scenario.
Real‑World Use Case: E‑Commerce API on a 2‑Core VPS
My client runs a boutique e‑commerce platform built with NestJS. The API receives 150‑200 requests per second during flash sales. After a codebase cleanup, the dev team renamed the entry file from main.js to server.js but forgot to update the PM2 config.
The next morning the sales page displayed a 502 error for 5 minutes. The checkout API never hit the database, and every aborted cart turned into a lost sale—roughly $12,000 in revenue.
Following the steps above, we:
- Caught the misconfiguration in the
pm2 listoutput. - Updated
script: "./dist/server.js"in the ecosystem file. - Added a
postinstallhook to rebuild automatically.
The fix took under 10 minutes, and the uptime monitor showed 100% availability within the next hour.
Results & Outcome
After implementing the corrected PM2 config and adding a CI health‑check, the following metrics improved dramatically:
| Metric | Before | After |
|---|---|---|
| Average response time | 250 ms | 180 ms |
| Uptime (last 30 days) | 99.2 % | 99.99 % |
| Revenue loss (per incident) | $12k | $0 |
Beyond the numbers, the team gained confidence that their deployment pipeline catches such slip‑ups before they hit production.
Bonus Tips to Keep Your NestJS App Rock‑Solid
- Enable PM2’s built‑in
watchmode only in development. In production, rely on zero‑downtime reloads (pm2 reload all). - Use a process supervisor like
systemdto auto‑restart PM2 after a server reboot. - Expose a health endpoint. A simple
GET /healththat returns{status:'ok'}makes monitoring painless. - Pin Node version in
.nvmrcand enforce it in CI to avoid binary mismatches. - Log PM2 output to separate files.
error_file: './logs/err.log'andout_file: './logs/out.log'help you spot crashes fast.
Warning: Never run pm2 delete all on a live server without a backup plan. It instantly kills every Node process and can trigger the exact 502 you’re trying to avoid.
Monetize Your Knowledge
If you’ve saved time (or money) with this guide, consider turning your expertise into a side hustle:
- Write a paid “Deploy NestJS with PM2” cheat sheet and sell it on Gumroad.
- Offer a one‑hour consulting call to audit a client’s deployment pipeline.
- Create a short video tutorial and host it on Udemy or Skillshare.
Even a few sales per month can offset the cost of your VPS and generate passive income.
© 2026 Your Name – All rights reserved. This article is for educational purposes only.
No comments:
Post a Comment