Troubleshooting Nginx worker_connections Limit Reached on Ubuntu 20.04 LTS
Resolve Nginx 'worker_connections limit reached' errors on Ubuntu 20.04 LTS by optimizing server and Nginx configurations for high traffic. Boost performance!
Resolve Nginx 'worker_connections limit reached' errors on Ubuntu 20.04 LTS by optimizing server and Nginx configurations for high traffic. Boost performance!
When managing high-traffic web services, encountering the "Nginx workers connection limit reached" error can be a significant performance bottleneck, leading to service degradation or outright unavailability. This guide provides a comprehensive, technical walkthrough to diagnose and resolve this common issue on an Ubuntu 20.04 LTS system running Nginx, ensuring your web server can handle the anticipated load.
Symptom & Error Signature
Users attempting to access your website or web application may experience:
- 502 Bad Gateway errors
- 504 Gateway Timeout errors
- Connection refused messages
- Extremely slow page loading or incomplete content delivery
In your Nginx error logs (typically located at /var/log/nginx/error.log), you will observe entries similar to these:
2023/10/26 10:30:05 [crit] 12345#12345: *1234567 accept() failed (24: Too many open files)
2023/10/26 10:30:06 [alert] 12346#12346: *1234568 could not accept connection, worker_connections are not enough
2023/10/26 10:30:07 [crit] 12347#12347: *1234569 accept() failed (102: Network is unreachable) while accepting new connection on 0.0.0.0:80
System logs (e.g., dmesg or journalctl) might also show "kernel: VFS: file-max limit reached" or similar entries related to file descriptor exhaustion.
Root Cause Analysis
The "Nginx worker_connections limit reached" error signifies that an Nginx worker process has hit the maximum number of simultaneous connections it's configured to handle. This can stem from several underlying factors:
- Insufficient
worker_connections: The primary cause is often aworker_connectionsdirective innginx.confthat is set too low for the current traffic demands. Nginx's default configuration is conservative and may not suit production environments. - System-wide File Descriptor Limits (
ulimit -n): Each connection (including client connections, upstream connections, and file handles) consumes a file descriptor. The operating system imposes a limit on the number of file descriptors an individual process or user can open. If thisnofile(number of files) limit is lower than Nginx'sworker_connections, Nginx cannot effectively utilize its configured capacity. - Low
worker_processes: While less direct, having too fewworker_processesmeans the burden of all connections is distributed among fewer processes, potentially causing each to hit itsworker_connectionslimit faster, especially on multi-core systems. - Slow Upstream Servers or Application Issues: If your backend application servers (e.g., PHP-FPM, Node.js, Python Gunicorn) are slow to respond or frequently hang, Nginx worker processes will hold open connections longer, exhausting available
worker_connectionseven with moderate traffic. - Persistent Connections (Keepalives): While beneficial for performance, excessively long
keepalive_timeoutsettings on high-traffic sites can tie up worker connections for clients that are no longer active, effectively reducing the number of available slots for new connections. - High Traffic Volume: A sudden, legitimate surge in traffic (e.g., a viral event) or a Distributed Denial of Service (DDoS) attack can push a well-configured server beyond its capacity.
Step-by-Step Resolution
This section details how to systematically increase Nginx's connection handling capacity and address underlying system limits.
1. Assess Current Nginx Configuration
First, let's examine your current Nginx configuration to understand the baseline.
# Locate Nginx configuration files
sudo nginx -t
# Check current worker_connections value
grep -r "worker_connections" /etc/nginx/
# Check current worker_processes value
grep -r "worker_processes" /etc/nginx/
2. Increase worker_connections in Nginx Configuration
The worker_connections directive, located within the events block of your nginx.conf, defines the maximum number of simultaneous connections that a single worker process can open.
Open the Nginx main configuration file:
sudo nano /etc/nginx/nginx.confLocate the
eventsblock and modifyworker_connections:Find the
events { ... }block. Ifworker_connectionsis present, increase its value. If not, add it. A common starting point is 4096, 8192, or even 16384 for high-traffic servers. The absolute theoretical maximum is 65535, but practical limits apply based on RAM and OS configuration.events { worker_connections 8192; # Or 4096, 16384, etc. # multi_accept on; # Consider uncommenting for very high traffic }Each connection consumes a small amount of RAM. While increasing
worker_connectionssignificantly improves concurrency, be mindful of your server's available memory. Overly aggressive values without sufficient RAM can lead to swapping and performance degradation.Test Nginx configuration for syntax errors:
sudo nginx -tYou should see
syntax is okandtest is successful.Reload Nginx to apply changes:
sudo systemctl reload nginx
3. Adjust System-Wide Open File Limits (ulimit -n)
Nginx worker processes are constrained by the operating system's per-process file descriptor limits. If this limit (often referred to as nofile) is lower than your worker_connections setting, Nginx won't be able to reach its configured capacity.
Check the current
nofilelimit for the Nginx process:First, find the PID of an Nginx worker process:
ps aux | grep nginx | grep workerThen, check its limits:
cat /proc/<Nginx_Worker_PID>/limits | grep "Max open files"Replace
<Nginx_Worker_PID>with an actual PID from theps auxcommand.Modify
/etc/security/limits.conf:Edit the file
/etc/security/limits.confto set a highernofilelimit for the user Nginx runs as (typicallywww-dataon Ubuntu).sudo nano /etc/security/limits.confAdd the following lines at the end of the file, replacing
www-dataif your Nginx user is different:# Nginx limits www-data soft nofile 65535 www-data hard nofile 65535soft: The current limit, which can be increased by the user up to the hard limit.hard: The maximum limit that can be set.
Incorrect entries in
limits.confcan prevent users or services from logging in or starting. Ensure the format is correct. The65535value should be equal to or higher than yourworker_connectionssetting.Ensure
pam_limits.sois enabled:For
limits.confto take effect, thepam_limits.somodule must be enabled in PAM. Check the following files:sudo nano /etc/pam.d/common-session sudo nano /etc/pam.d/common-session-noninteractiveEnsure that the line
session required pam_limits.sois present and uncommented in both.Configure Systemd for Nginx service:
For services managed by Systemd (like Nginx),
limits.confmight not be fully effective without additional configuration. It's best practice to set theLimitNOFILEdirectly in a Systemd override file.Create or edit the override file for Nginx:
sudo systemctl edit nginx.serviceThis will open a new editor session for
/etc/systemd/system/nginx.service.d/override.conf. Add the following content:[Service] LimitNOFILE=65535Save and exit the editor.
Reload Systemd and restart Nginx:
sudo systemctl daemon-reload sudo systemctl restart nginxVerify the new
nofilelimit:After restarting, check the Nginx worker process limits again:
cat /proc/$(sudo systemctl show --property MainPID nginx | cut -d'=' -f2)/limits | grep "Max open files"The
Max open filesvalue should now reflect your new setting (e.g.,65535).
4. Optimize worker_processes
worker_processes defines how many Nginx worker processes will run. A good rule of thumb is to set this to the number of CPU cores available on your server.
Count your CPU cores:
grep processor /proc/cpuinfo | wc -lEdit
nginx.conf:sudo nano /etc/nginx/nginx.confFind the
worker_processesdirective at the top of the file. You can either set it toauto(recommended for Nginx 1.8+) or a specific number (e.g.,4for a quad-core CPU).worker_processes auto; # Nginx will automatically determine the optimal number # worker_processes 4; # Or set a specific number like 1, 2, 4, etc.Test configuration and reload Nginx:
sudo nginx -t sudo systemctl reload nginx
5. Fine-tune TCP Connection Recycling (Ephemeral Ports)
When Nginx acts as a reverse proxy, it establishes outbound connections to upstream servers. If your server is under extremely heavy load, it might exhaust the available ephemeral ports for outbound connections, even if Nginx itself has enough worker_connections for inbound client traffic.
Increase the ephemeral port range:
sudo nano /etc/sysctl.confAdd or modify the following line to expand the range of local ports available for outgoing connections:
net.ipv4.ip_local_port_range = 1024 65000Apply sysctl changes:
sudo sysctl -p
6. Review Nginx Keepalive Settings (Optional, but Recommended)
Nginx's keepalive_timeout and keepalive_requests settings affect how long Nginx keeps a connection open after a request and how many requests can be served over a single connection, respectively. While generally good for performance, excessively high values on very busy sites can tie up worker connections.
Inspect Nginx configuration for keepalive settings:
grep -r "keepalive_timeout" /etc/nginx/ grep -r "keepalive_requests" /etc/nginx/Consider adjustments in
http,server, orlocationblocks:keepalive_timeout 60s;: A value between 15-75 seconds is common. If users are very interactive, a higher value is good; for mostly static content, a lower value might free up connections faster.keepalive_requests 100;: Default is 100. For APIs or highly interactive sites, increasing this to 1000 or more can be beneficial.
Adjust these values based on your application's specific traffic patterns and client behavior. Always test changes thoroughly.
http { # ... other http settings keepalive_timeout 60s; keepalive_requests 200; # ... }Test configuration and reload Nginx:
sudo nginx -t sudo systemctl reload nginx
By following these steps, you will significantly enhance Nginx's capacity to handle simultaneous connections, resolving the "worker_connections limit reached" error and improving the overall stability and performance of your web server on Ubuntu 20.04 LTS. Remember to monitor your server's resources (CPU, RAM, open files) after making changes to ensure optimal performance.