Sunday, May 3, 2026

How to Fix the “Maximum Socket Connections Exceeded” Error When Deploying a NestJS API to a VPS with Nginx and PM2

How to Fix the “Maximum Socket Connections Exceeded” Error When Deploying a NestJS API to a VPS with Nginx and PM2

You finally built a slick NestJS API, pushed it to a cheap VPS, and watched the traffic roll in… until Nginx threw a “Maximum socket connections exceeded” error. The whole thing grinds to a halt, users see blank pages, and your hard‑earned reputation takes a hit. Don’t panic—this guide shows you how to diagnose and squash the problem in minutes so your service stays fast, reliable, and profitable.

Why This Matters

If your API can’t handle concurrent connections, you lose customers, churn revenue, and risk bad reviews. The “Maximum socket connections exceeded” message is Nginx’s way of saying the underlying OS or your process manager (PM2) has hit a hard limit. Fixing it not only restores uptime, it also scales your app for future growth without throwing more money at a bigger VPS.

Quick TL;DR

  • Increase the OS file‑descriptor limit (ulimit).
  • Adjust Nginx worker_connections and worker_rlimit_nofile.
  • Configure PM2 max_memory_restart and instances to spread load.
  • Restart services and test with ab or wrk.

Step‑by‑Step Tutorial

1. Check the Current Limits

Run these commands on your VPS to see what the OS thinks is “enough”.

ulimit -n
cat /proc/sys/fs/file-max
cat /etc/security/limits.conf

2. Raise the File‑Descriptor (FD) Limit

Open /etc/security/limits.conf and add (or edit) the lines below. This tells the system each user can open up to 65535 sockets.

*               soft    nofile          65535
*               hard    nofile          65535

Next, edit /etc/sysctl.conf to raise the global max:

fs.file-max = 2097152

Apply the changes without rebooting:

sysctl -p
ulimit -n 65535
Tip: Add ulimit -n 65535 to /etc/profile.d/custom.sh so it persists after a reboot.

3. Configure Nginx for High Concurrency

Open your site config (usually /etc/nginx/sites-available/yourdomain.conf) and adjust the worker settings.

worker_processes auto;
worker_rlimit_nofile 100000;

events {
    worker_connections 8192;
    multi_accept on;
}

Don’t forget to reload Nginx:

systemctl reload nginx
Warning: Setting worker_connections too high on a low‑end VPS can cause memory pressure. Stick to 8‑12k per core unless you know you have RAM to spare.

4. Optimize PM2 Settings for NestJS

PM2 spawns Node processes and can also hit socket limits. Use the ecosystem file to tell PM2 how many instances to run and when to recycle memory.

// ecosystem.config.js
module.exports = {
  apps: [{
    name: "nestjs-api",
    script: "dist/main.js",
    instances: "max",          // auto‑detect CPU cores
    exec_mode: "cluster",
    max_memory_restart: "300M", // restart if >300MB
    env: {
      NODE_ENV: "production"
    }
  }]
};

Deploy the config and restart PM2:

pm2 start ecosystem.config.js
pm2 save
pm2 restart all

5. Verify the Fix

Run a quick load test against your API endpoint. You should see no “socket” errors.

# Using wrk (install with: apt install wrk)
wrk -t12 -c200 -d30s http://yourdomain.com/api/health

If the Latency line stays low and Errors = 0, you’re good to go.

Real‑World Use Case

Imagine you run a SaaS that bills $49/mo per client. A single client spikes traffic during a product launch, sending 500 concurrent requests per second. Before applying the steps above, Nginx would choke at ~200 sockets, causing a 15‑minute outage and a $735 loss. After raising FD limits and clustering with PM2, the same VPS handled 2,500 RPS with zero errors, preserving revenue and keeping the client happy.

Results / Outcome

  • ✔️ Socket‑related 502/504 errors eliminated.
  • ✔️ CPU usage stays under 70 % even at peak load.
  • ✔️ Memory consumption stays predictable thanks to max_memory_restart.
  • ✔️ You can now safely increase your pricing or add premium plans without fearing downtime.

Bonus Tips

  • Enable HTTP/2. Add listen 443 ssl http2; to your Nginx block for faster multiplexed connections.
  • Use Keep‑Alive. In nginx.conf set keepalive_timeout 65; to reduce handshake overhead.
  • Monitor with Netdata or Prometheus. Visual dashboards catch limits before they bite.
  • Automate the setup. Put all the commands in an Ansible playbook so new servers are ready in minutes.

Monetization (Optional)

If you’re selling hosting or consulting services, package this “High‑Performance NestJS Deploy” as a premium offering. charge $199–$399 per VPS setup and include ongoing monitoring. The time you save fixing socket limits translates directly into billable hours.

Ready to get your NestJS API running like a champ? Apply the steps above, watch the sockets stay under control, and keep the cash flowing.

No comments:

Post a Comment