Fixing Nginx worker_connections Limit Reached on Ubuntu 22.04 LTS
Troubleshoot and resolve Nginx 'worker_connections limit reached' errors on Ubuntu 22.04 LTS by adjusting Nginx configuration and system limits for high-traffic web applications.
Troubleshoot and resolve Nginx 'worker_connections limit reached' errors on Ubuntu 22.04 LTS by adjusting Nginx configuration and system limits for high-traffic web applications.
Nginx is renowned for its high performance and efficiency as a web server and reverse proxy. However, even the most robust systems can encounter bottlenecks under extreme load or misconfiguration. One common issue for high-traffic websites is the "Nginx workers connection limit reached" error, directly related to the worker_connections directive. This guide will walk you through diagnosing and resolving this critical performance limitation on an Ubuntu 22.04 LTS server.
Symptom & Error Signature
When the Nginx worker_connections limit is reached, users typically experience:
- Slow website loading times.
- Browser errors such as "Connection refused," "502 Bad Gateway," or "504 Gateway Timeout."
- Inability to connect to the website during peak traffic.
The most definitive sign is an alert message in your Nginx error logs (commonly located at /var/log/nginx/error.log), indicating that the connection limit for a worker process has been hit.
2023/10/26 14:35:01 [alert] 1234#1234: *123456789 worker_connections limit reached, client: 192.168.1.100, server: example.com, request: "GET /index.html HTTP/1.1", host: "example.com"
In some configurations, especially with older Nginx versions or specific log levels, you might see [warn] or [info] instead of [alert], but the core message remains the same.
Root Cause Analysis
The "Nginx worker_connections limit reached" error fundamentally means that an individual Nginx worker process has exhausted its allocated capacity for managing concurrent client connections. Understanding the interplay of several Nginx and system-level directives is crucial for a complete resolution:
worker_connectionsDirective: This Nginx directive, defined within theeventsblock ofnginx.conf, specifies the maximum number of simultaneous connections that a single Nginx worker process can open. This includes both incoming client connections and outgoing connections to upstream servers (e.g., PHP-FPM, Node.js, database). The total theoretical maximum connections Nginx can handle isworker_processes * worker_connections.File Descriptors (
ulimit -n): Every connection Nginx handles consumes a file descriptor (FD). Theworker_connectionsvalue must not exceed the maximum number of open file descriptors allowed for the Nginx process by the operating system. Linux systems have a defaultulimit -n(max open files) that is often 1024 or 4096, which is frequently insufficient for busy Nginx servers. Ifworker_connectionsis set higher thanulimit -n, Nginx will still be limited by the operating system's constraint.worker_processesDirective: This directive determines how many Nginx worker processes run. Each worker process is an independent entity capable of handlingworker_connections. Ifworker_processesis set too low (e.g., the default of 1), Nginx cannot fully utilize the server's CPU cores, leading to saturation of the single worker even ifworker_connectionsis high.Backend Bottlenecks: While Nginx itself might be well-tuned, slow responses from backend applications (e.g., PHP-FPM, Gunicorn, databases) can cause Nginx connections to remain open longer than necessary. This prolonged connection state can prematurely consume
worker_connectionsslots, even if Nginx's processing capacity is not the primary issue.Traffic Spikes or DDoS Attacks: A sudden and unexpected surge in legitimate traffic or a malicious Distributed Denial of Service (DDoS) attack can overwhelm even a perfectly tuned Nginx configuration, quickly exhausting connection limits.
Step-by-Step Resolution
Resolving this issue involves a combination of adjusting Nginx configuration directives and increasing system-level resource limits.
1. Verify Current Nginx Configuration and System Limits
First, gather information about your current Nginx setup and system limits.
Check Nginx
worker_processesandworker_connections:grep -E "worker_processes|worker_connections" /etc/nginx/nginx.confTypical output might look like:
worker_processes auto; worker_connections 768;Check
ulimit -nfor the Nginx process: Find an Nginx master or worker process ID:PID=$(ps aux | grep "[n]ginx: master process" | awk '{print $2}') # Or for a worker process: # PID=$(ps aux | grep "[n]ginx: worker process" | head -n 1 | awk '{print $2}') echo "Nginx Master PID: $PID"Now, check its file descriptor limits:
sudo cat /proc/$PID/limits | grep "Max open files"This will show you the
SoftandHardlimits for file descriptors. Alternatively, if Nginx runs aswww-datauser:sudo -u www-data bash -c 'ulimit -n'This shows the
softlimit for the user.
2. Adjust worker_connections in Nginx Configuration
Increase the worker_connections value in your main Nginx configuration file, typically /etc/nginx/nginx.conf.
Open the Nginx configuration file:
sudo nano /etc/nginx/nginx.confLocate the
eventsblock and modify theworker_connectionsdirective.# /etc/nginx/nginx.conf user www-data; worker_processes auto; # Or specify number of CPU cores, e.g., 4 or 8 pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { # Increase this value. Common values are 1024, 2048, 4096, 8192, 16384, 32768. # Start with 4096 or 8192 and monitor. worker_connections 8192; # multi_accept on; # Uncomment for higher throughput if connections are short-lived }
The
worker_connectionsvalue defines the maximum connections per worker process. The ideal value depends on your server's hardware, expected traffic, and the nature of connections (short-lived vs. long-lived). Do not set it excessively high without also increasing the system's file descriptor limits, as Nginx will still be constrained by the OS.
3. Increase System File Descriptor Limits for Nginx
This is a critical step. The worker_connections value cannot exceed the system's file descriptor limit for the Nginx process. We'll use the recommended Systemd override method.
Method A: Systemd Service Unit (Recommended for Ubuntu 22.04 LTS)
Create a Systemd override file for the Nginx service. This ensures that your changes persist updates and specifically apply to the Nginx service.
Create an override file for the Nginx service:
sudo systemctl edit nginxThis command will open an editor (usually
nanoorvi) for a new file/etc/systemd/system/nginx.service.d/override.conf.Add or modify the
LimitNOFILEdirective within the[Service]section:# /etc/systemd/system/nginx.service.d/override.conf [Service] LimitNOFILE=65536 # Or higher, e.g., 1048576 (1M)The
LimitNOFILEvalue should be at least double yourworker_connectionssetting to account for upstream connections, log files, etc. For high-traffic servers, values like 65536, 524288 (512K), or 1048576 (1M) are common.Save the file and exit the editor.
Reload the Systemd manager configuration and restart Nginx:
sudo systemctl daemon-reload sudo systemctl restart nginx
The
LimitNOFILEvalue is the maximum number of file descriptors the Nginx service can open. This value must be greater than or equal to yourworker_connectionssetting. A good rule of thumb is to setLimitNOFILEto at least2 * worker_connections, or even higher (e.g., 4x) for busy proxy servers.
Method B:
/etc/security/limits.conf(Less precise for specific services)While less granular than Systemd overrides for specific services, you can also modify
/etc/security/limits.conf. This affects all processes launched by the specified user.Open the
limits.conffile:sudo nano /etc/security/limits.confAdd or modify lines for the Nginx user (commonly
www-dataornginx):# /etc/security/limits.conf # <domain> <type> <item> <value> www-data soft nofile 65536 www-data hard nofile 65536Replace
www-datawith your Nginx user if it's different.Save the file. For these changes to take effect, you typically need to reboot the server or at least log out and back in for the user, and then restart Nginx. The Systemd method is generally preferred for immediate, service-specific application.
Modifying
limits.confaffects all processes run by the specified user. Ensure you understand the implications for other applications running under the same user account.
4. Adjust worker_processes (if necessary)
The worker_processes directive dictates how many worker processes Nginx will spawn. Each process independently handles connections up to its worker_connections limit.
Open the Nginx configuration file:
sudo nano /etc/nginx/nginx.confSet
worker_processestoautoor to the number of CPU cores available on your server.# /etc/nginx/nginx.conf worker_processes auto; # Recommended: Nginx will determine optimal number based on CPU coresIf you prefer to manually specify, you can count your CPU cores with
nprocorgrep -c ^processor /proc/cpuinfo. For example, for a 4-core CPU:worker_processes 4;
worker_processes auto;is generally the best setting as Nginx will dynamically determine the optimal number of worker processes based on the server's CPU capabilities. Manual specification might be useful in niche cases where you want to reserve cores for other services.
5. Test Configuration and Restart Nginx
After making any changes to Nginx configuration or Systemd units, always test before applying.
Test Nginx configuration syntax:
sudo nginx -tYou should see
syntax is okandtest is successful. If there are errors, correct them before proceeding.Restart Nginx service:
sudo systemctl restart nginxVerify the new limits for Nginx worker processes: After restarting, get the PID of a worker process:
PID=$(ps aux | grep "[n]ginx: worker process" | head -n 1 | awk '{print $2}') sudo cat /proc/$PID/limits | grep "Max open files"Confirm that the
Max open files(both soft and hard) reflects theLimitNOFILEyou set in Systemd.
6. Monitor Performance and Logs
After implementing the changes, continuous monitoring is crucial to ensure the issue is resolved and to identify any new bottlenecks.
Nginx Error Logs: Keep an eye on
/var/log/nginx/error.logfor any recurrence of theworker_connections limit reachedalert.sudo tail -f /var/log/nginx/error.logSystem Resource Monitoring: Use tools like
htop,atop,nmon, ornetdatato monitor CPU utilization, memory usage, and network I/O.htopActive Connections: Check the number of active network connections:
sudo ss -tuna | grep ":80|:443" | wc -lNginx Status (if configured): If you have
stub_statusenabled, you can monitor Nginx's internal metrics:curl http://127.0.0.1/nginx_status(Ensure
stub_status on;is configured in your Nginx server block, usually atlocation /nginx_status { ... }.)
Additional Considerations
- Keepalive Timeout: For HTTP/1.x, if connections are held open for too long due to high
keepalive_timeoutsettings and clients are not reusing them, connections can be tied up unnecessarily. Consider reducingkeepalive_timeoutif applicable. - Upstream Connection Pooling: If Nginx is acting as a reverse proxy, ensure your upstream servers (e.g., PHP-FPM, Gunicorn) can handle the increased load. Also, consider using
keepalivedirectives in yourupstreamblocks to reuse connections to backend servers. - DDoS Protection & Rate Limiting: If the connection limit issues are due to malicious traffic or overwhelming traffic spikes, consider implementing Nginx's built-in
limit_reqandlimit_connmodules for rate limiting, or deploy a Web Application Firewall (WAF) or dedicated DDoS mitigation service. - Horizontal Scaling: For extremely high-traffic scenarios that exceed the capacity of a single server, consider scaling horizontally by distributing traffic across multiple Nginx servers using a load balancer (e.g., HAProxy, AWS ELB, Nginx Plus).
By systematically applying these steps, you can effectively resolve the "Nginx workers connection limit reached" error, ensuring your Ubuntu 22.04 LTS server remains performant and responsive under heavy loads.
Our Production Verification Guarantee
Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.