Nginx "Worker_connections Exceeded" Error Fix
Hitting Nginx's worker_connections limit means each worker process has reached the maximum number of simultaneous connections it's configured to handle — this is a deliberate ceiling, and raising it safely requires also checking the underlying system limits it depends on.
The Problem
Under load, Nginx's error log shows entries like:
*1234 worker_connections are not enough while connecting to upstream
New connections start failing or queuing noticeably, even though the server itself doesn't appear to be out of CPU or memory resources.
Why It Happens
worker_connections sets a hard cap, per worker process, on how many simultaneous connections that worker can handle — including both client connections and any upstream connections Nginx itself makes as a proxy. Common causes of hitting this limit:
- The default value (often 512 or 1024, depending on the distribution) is genuinely too low for the actual traffic the server needs to handle
- Nginx is configured as a reverse proxy, and each client connection can require an additional upstream connection, effectively doubling the connection count needed per request compared to serving static files directly
- Long-lived connections (like WebSockets, or slow clients on slow networks) hold a connection open for much longer than a typical fast HTTP request, reducing the effective throughput of a fixed connection limit
- The underlying system-level file descriptor limit is lower than the configured
worker_connectionsvalue, silently capping the real maximum regardless of what Nginx's own config specifies
The Fix
First, check your current configuration to understand the actual ceiling in place:
grep -r worker_connections /etc/nginx/
Raise the value in the events block of your main Nginx configuration:
events {
worker_connections 4096;
}
The appropriate value depends heavily on your specific traffic pattern and available system resources — there's no universal correct number, but going from a default like 1024 to something in the 4096–8192 range is a common starting point for a moderately trafficked server before further tuning.
Critically, also check and raise the underlying system limit on open file descriptors, since each connection consumes a file descriptor, and Nginx can't actually reach its configured worker_connections value if the OS-level limit is lower:
ulimit -n
If this shows a low number (often 1024 by default on many systems), raise it both for the current session and permanently. For the Nginx service specifically, set it in the systemd unit file to ensure it applies correctly regardless of shell-level limits:
# /etc/systemd/system/nginx.service.d/override.conf
[Service]
LimitNOFILE=65536
sudo systemctl daemon-reload
sudo systemctl restart nginx
Also confirm the number of worker processes is appropriate for your server's CPU count, since total connection capacity is worker_processes × worker_connections, not just the per-worker value alone:
worker_processes auto;
Using auto lets Nginx match the number of worker processes to available CPU cores automatically, which is generally the right default rather than a manually guessed fixed number.
If you're running Nginx as a reverse proxy and upstream connections are a significant contributor to the total count, consider enabling connection keepalive to upstream servers, which reduces the overhead of constantly opening and closing new upstream connections for each request:
upstream backend {
server 127.0.0.1:3000;
keepalive 64;
}
Still Not Working?
If you've raised both worker_connections and the system file descriptor limit but still hit the ceiling under load, monitor actual connection counts in real time to understand whether the issue is genuinely sustained high traffic or a smaller number of connections being held open unnecessarily long (a common sign of slow or hanging upstream responses rather than raw volume):
watch -n 1 'ss -s'
If connections are piling up due to slow upstream responses rather than genuine traffic volume, the more effective fix is addressing the upstream slowness directly (or adding appropriate timeouts to fail fast rather than hold connections open indefinitely) rather than continuing to raise connection limits as a workaround for a performance problem elsewhere in the stack.