Resolve Nginx connection limit errors on CentOS Stream & Rocky Linux. Learn to tune worker_connections, file descriptors, and kernel parameters for high traffic.
When your Nginx web server experiences heavy traffic or misconfiguration, you might encounter issues where new connections are dropped, requests time out, or users see "502 Bad Gateway" or "503 Service Unavailable" errors. A common underlying cause on high-load systems is hitting the Nginx worker connection limit, leading to performance degradation or complete service interruption. This guide will walk you through diagnosing and resolving this critical issue on CentOS Stream and Rocky Linux environments.
Symptom & Error Signature
Users will typically experience slow page loads, connection refused errors, or HTTP 502/503 status codes. In the Nginx error logs, usually found at /var/log/nginx/error.log, you will observe messages similar to these:
2023/10/26 14:35:01 [alert] 1234#1234: *1234567 too many open files: 1024, max_connections: 1024 (client: 192.168.1.1, server: example.com, request: "GET / HTTP/1.1", host: "example.com")
2023/10/26 14:35:02 [alert] 1234#1234: *1234568 worker_connections are not enough while connecting to upstream (X.X.X.X:80)
2023/10/26 14:35:03 [crit] 1235#1235: *1234569 accept() failed (24: Too many open files)
These error messages clearly indicate that Nginx workers are unable to establish new connections, either due to their own configured limits or system-wide file descriptor constraints.
Root Cause Analysis
The "Nginx workers connection limit reached" error typically stems from one or more of the following underlying issues:
- Insufficient
workerconnections: This is the most direct cause. Theworkerconnectionsdirective innginx.confdefines the maximum number of simultaneous connections that a single Nginx worker process can handle. If the aggregate capacity (workerprocesses * workerconnections) is lower than the actual peak concurrent connections, Nginx will drop new requests. - Too Few
workerprocesses: Whileworkerconnectionslimits individual workers,workerprocessesdetermines how many workers Nginx spawns. If this value is too low, the server might not fully utilize available CPU cores, bottlenecking processing capacity even ifworkerconnectionsis high per worker. - System-wide File Descriptor Limits (
ulimit -n): Nginx is a file descriptor (FD)-intensive application. Each client connection, as well as connections to upstream servers, uses at least one file descriptor. If the operating system's per-process file descriptor limit (ulimit -n) for the Nginx process is lower than its configuredworker_connections, Nginx will fail with "Too many open files" errors before reaching its internal connection limit. - Kernel TCP Backlog Limits (
net.core.somaxconn,net.ipv4.tcpmaxsyn_backlog): These kernel parameters control the maximum length of the queue for pending TCP connections. If Nginx processes established connections slower than new connections arrive, these queues can overflow, leading to dropped connections even before Nginx can accept them, often presenting as connection resets on the client side. - Upstream Server Bottlenecks: If Nginx is configured as a reverse proxy, a slow or overloaded upstream application server (e.g., PHP-FPM, Node.js app, Tomcat) can cause Nginx worker processes to wait for responses, holding open connections and thereby exhausting the
worker_connectionspool prematurely.
Step-by-Step Resolution
Follow these steps to diagnose and resolve the Nginx worker connection limit issue.
1. Analyze Current Nginx & System Configuration
Before making changes, understand your current settings:
First, identify the Nginx master process ID:
`bash
sudo systemctl status nginx | grep Main PID
# Example output: Main PID: 1234 (nginx)
`
Replace 1234 with your Nginx master PID in subsequent commands.
- Check Nginx
workerprocessesandworkerconnections: -
`bash - grep -E 'workerprocesses|workerconnections' /etc/nginx/nginx.conf
-
` - Check Nginx process's file descriptor limit:
-
`bash - cat /proc/$(sudo systemctl show –property MainPID nginx | cut -d= -f2)/limits | grep 'Max open files'
-
` - Compare this "Max open files" (soft limit) with your
workerconnectionsvalue.workerconnectionsmust be less than or equal to this limit. - Check system-wide kernel TCP backlog settings:
-
`bash - sysctl net.core.somaxconn net.ipv4.tcpmaxsyn_backlog
-
`
2. Adjust Nginx workerconnections and workerprocesses
Modify the Nginx main configuration file, typically /etc/nginx/nginx.conf.
- Open the Nginx configuration file:
-
`bash - sudo vi /etc/nginx/nginx.conf
-
` - Adjust
workerprocessesandworkerconnections: - Locate the
worker_processesandeventsblocks. - * Set
worker_processestoautoto allow Nginx to detect the optimal number of processes based on CPU cores, or explicitly to the number of CPU cores available on your server. - * Significantly increase
worker_connections. A common starting point for high-traffic sites is10240or20480. You can go higher, but remember each connection consumes some memory. - * Consider adding
multi_accept on;in theeventsblock. This tells a worker process to accept as many new connections as possible at once, rather than one by one, which can be beneficial under very high load.
user nginx; worker_processes auto; # Set to 'auto' or the number of CPU cores (e.g., 4, 8)
error_log /var/log/nginx/error.log warn; pid /run/nginx.pid;
events { worker_connections 20480; # Increase this value significantly (e.g., 10240, 20480, 40960) multi_accept on; # Optional: Enable multiple connection accepts per worker }
http { include /etc/nginx/mime.types; default_type application/octet-stream;
… other http directives …
}
`
3. Test Nginx configuration:
`bash
sudo nginx -t
`
Ensure you see syntax is ok and test is successful.
4. Reload Nginx service:
`bash
sudo systemctl reload nginx
`
[!IMPORTANT] The total number of concurrent connections Nginx can theoretically handle is
workerprocesses workerconnections. Ensure this value is adequate for your anticipated peak traffic but also mindful of your server's RAM and CPU resources. A common guideline is to setworker_connectionsto at least2 UlimitNOFILEto account for both client and upstream connections.
3. Increase System-wide File Descriptor Limits (ulimit)
The Nginx process's file descriptor limit must be equal to or greater than its worker_connections setting. We'll modify the Systemd service unit for Nginx to achieve this.
- Create or edit the Nginx Systemd override file:
-
`bash - sudo systemctl edit nginx
-
` - This will open a file like
/etc/systemd/system/nginx.service.d/override.conf. - Add the
LimitNOFILEdirective: - Add the following lines to the file, setting
LimitNOFILEto a value higher than yourworker_connections(e.g.,65536or131072).
[Service]
LimitNOFILE=65536
```
3. **Save and exit.**
4. **Reload the Systemd daemon:**
```bash
sudo systemctl daemon-reload
```
5. **Restart Nginx to apply changes:**
```bash
sudo systemctl restart nginx
```
6. **Verify the new `ulimit` for the Nginx process:**
```bash
cat /proc/$(sudo systemctl show --property MainPID nginx | cut -d= -f2)/limits | grep 'Max open files'
```
[!WARNING] While increasing
LimitNOFILEallows Nginx to handle more connections, setting it excessively high without sufficient RAM can lead to memory exhaustion and system instability. Start with65536or131072and monitor your server's performance.
4. Tune Kernel TCP Backlog Parameters
Adjusting kernel parameters can help the system handle bursts of new connections more gracefully.
- Create or edit a custom
sysctlconfiguration file: -
`bash - sudo vi /etc/sysctl.d/90-custom.conf
-
` - (You can also use
/etc/sysctl.conf, but.dfiles are cleaner for custom settings). - Add or modify the following parameters:
# Maximum number of connections that can be queued for a listening socket
Maximum number of SYN requests that the kernel will keep in memory net.ipv4.tcpmaxsyn_backlog = 8192
Allow reusing sockets in TIME_WAIT state for new connections (can help with port exhaustion) net.ipv4.tcptwreuse = 1
Reduce TIME_WAIT state duration (for faster socket cleanup)
net.ipv4.tcpfintimeout = 30
`
3. Save and exit.
4. Apply the sysctl changes:
`bash
sudo sysctl -p /etc/sysctl.d/90-custom.conf
`
(Or sudo sysctl -p if you edited /etc/sysctl.conf).
5. Verify the new kernel parameters:
`bash
sysctl net.core.somaxconn net.ipv4.tcpmaxsynbacklog net.ipv4.tcptwreuse net.ipv4.tcpfin_timeout
`
[!NOTE]
net.core.somaxconnaffects thelistendirective'sbacklogparameter in Nginx.net.ipv4.tcpmaxsyn_backlogis crucial for preventing SYN flood attacks and managing a high rate of new connection attempts. These values should be adjusted incrementally based on your specific traffic patterns and monitoring.
5. Monitor and Optimize
After implementing these changes, continuous monitoring is crucial to ensure stability and optimal performance.
- Monitor Nginx error logs: Keep an eye on
/var/log/nginx/error.logfor any new connection-related errors. - System resource monitoring: Use tools like
atop,htop,dstat, orgrafana/prometheusto monitor CPU, memory, and network usage. - Network statistics:
- * Check for connections in various states:
netstat -nat | awk '{print $NF}' | sort | uniq -c | sort -nr - * Summarize network statistics:
ss -s - Nginx Stub Status Module: If enabled, monitor Nginx's active connections and requests per second:
-
`bash - curl -s http://localhost/nginx_status
-
` - (Requires
stubstatusto be enabled in your Nginx configuration, e.g., in a server block:location /nginxstatus { stub_status on; allow 127.0.0.1; deny all; }). - Further Nginx Optimization:
- * Consider
keepalivetimeoutandkeepaliverequestsif your application benefits from persistent connections. - * Optimize proxy buffering settings (
proxybuffering,proxybuffers,proxybuffersize) if Nginx is a reverse proxy. - * Ensure your upstream application servers (e.g., PHP-FPM, uWSGI, Node.js) are also adequately scaled and configured to handle the increased load Nginx is now passing to them.
By systematically adjusting Nginx configuration and underlying OS limits, you can significantly improve your server's ability to handle high concurrent connections, ensuring a more stable and responsive web service.
Leave a Reply