{"id":89,"date":"2026-07-15T00:00:00","date_gmt":"2026-07-15T00:00:00","guid":{"rendered":"http:\/\/\/var\/www\/html\/?p=89"},"modified":"2026-07-21T01:02:34","modified_gmt":"2026-07-21T01:02:34","slug":"nginx-workers-connection-limit-reached-workerconnections-on-centos-stream-rocky-linux","status":"publish","type":"post","link":"https:\/\/butitworkedlocal.com\/nginx-workers-connection-limit-reached-workerconnections-on-centos-stream-rocky-linux\/","title":{"rendered":"Troubleshooting &#8216;Nginx workers connection limit reached&#8217; on CentOS Stream \/ Rocky Linux"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Resolve Nginx connection limit errors on CentOS Stream &amp; Rocky Linux. Learn to tune worker_connections, file descriptors, and kernel parameters for high traffic.<\/strong><\/p>\n\n\n<p>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 &quot;502 Bad Gateway&quot; or &quot;503 Service Unavailable&quot; 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.<\/p>\n<h3>Symptom &amp; Error Signature<\/h3>\n<p>Users will typically experience slow page loads, connection refused errors, or HTTP 502\/503 status codes. In the Nginx error logs, usually found at <code>\/var\/log\/nginx\/error.log<\/code>, you will observe messages similar to these:<\/p>\n<pre><code class=\"language-log\">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: &quot;GET \/ HTTP\/1.1&quot;, host: &quot;example.com&quot;)\n2023\/10\/26 14:35:02 [alert] 1234#1234: *1234568 worker_connections are not enough while connecting to upstream (X.X.X.X:80)\n2023\/10\/26 14:35:03 [crit] 1235#1235: *1234569 accept() failed (24: Too many open files)\n<\/code><\/pre>\n<p>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.<\/p>\n<h3>Root Cause Analysis<\/h3>\n<p>The &quot;Nginx workers connection limit reached&quot; error typically stems from one or more of the following underlying issues:<\/p>\n<ol>\n<li><strong>Insufficient <code>worker_connections<\/code>:<\/strong> This is the most direct cause. The <code>worker_connections<\/code> directive in <code>nginx.conf<\/code> defines the maximum number of simultaneous connections that a single Nginx worker process can handle. If the aggregate capacity (<code>worker_processes * worker_connections<\/code>) is lower than the actual peak concurrent connections, Nginx will drop new requests.<\/li>\n<li><strong>Too Few <code>worker_processes<\/code>:<\/strong> While <code>worker_connections<\/code> limits individual workers, <code>worker_processes<\/code> determines how many workers Nginx spawns. If this value is too low, the server might not fully utilize available CPU cores, bottlenecking processing capacity even if <code>worker_connections<\/code> is high per worker.<\/li>\n<li><strong>System-wide File Descriptor Limits (<code>ulimit -n<\/code>):<\/strong> 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&#039;s per-process file descriptor limit (<code>ulimit -n<\/code>) for the Nginx process is lower than its configured <code>worker_connections<\/code>, Nginx will fail with &quot;Too many open files&quot; errors before reaching its internal connection limit.<\/li>\n<li><strong>Kernel TCP Backlog Limits (<code>net.core.somaxconn<\/code>, <code>net.ipv4.tcp_max_syn_backlog<\/code>):<\/strong> 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.<\/li>\n<li><strong>Upstream Server Bottlenecks:<\/strong> 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 <code>worker_connections<\/code> pool prematurely.<\/li>\n<\/ol>\n<h3>Step-by-Step Resolution<\/h3>\n<p>Follow these steps to diagnose and resolve the Nginx worker connection limit issue.<\/p>\n<h4>1. Analyze Current Nginx &amp; System Configuration<\/h4>\n<p>Before making changes, understand your current settings:<\/p>\n<p>First, identify the Nginx master process ID:<\/p>\n<pre><code class=\"language-bash\">sudo systemctl status nginx | grep Main PID\n# Example output: Main PID: 1234 (nginx)\n<\/code><\/pre>\n<p>Replace <code>1234<\/code> with your Nginx master PID in subsequent commands.<\/p>\n<ul>\n<li><strong>Check Nginx <code>worker_processes<\/code> and <code>worker_connections<\/code>:<\/strong><pre><code class=\"language-bash\">grep -E &#039;worker_processes|worker_connections&#039; \/etc\/nginx\/nginx.conf\n<\/code><\/pre>\n<\/li>\n<li><strong>Check Nginx process&#039;s file descriptor limit:<\/strong><pre><code class=\"language-bash\">cat \/proc\/$(sudo systemctl show --property MainPID nginx | cut -d= -f2)\/limits | grep &#039;Max open files&#039;\n<\/code><\/pre>\nCompare this &quot;Max open files&quot; (soft limit) with your <code>worker_connections<\/code> value. <code>worker_connections<\/code> must be less than or equal to this limit.<\/li>\n<li><strong>Check system-wide kernel TCP backlog settings:<\/strong><pre><code class=\"language-bash\">sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog\n<\/code><\/pre>\n<\/li>\n<\/ul>\n<h4>2. Adjust Nginx <code>worker_connections<\/code> and <code>worker_processes<\/code><\/h4>\n<p>Modify the Nginx main configuration file, typically <code>\/etc\/nginx\/nginx.conf<\/code>.<\/p>\n<ol>\n<li><p><strong>Open the Nginx configuration file:<\/strong><\/p>\n<pre><code class=\"language-bash\">sudo vi \/etc\/nginx\/nginx.conf\n<\/code><\/pre>\n<\/li>\n<li><p><strong>Adjust <code>worker_processes<\/code> and <code>worker_connections<\/code>:<\/strong>\nLocate the <code>worker_processes<\/code> and <code>events<\/code> blocks.<\/p>\n<ul>\n<li>Set <code>worker_processes<\/code> to <code>auto<\/code> to 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.<\/li>\n<li>Significantly increase <code>worker_connections<\/code>. A common starting point for high-traffic sites is <code>10240<\/code> or <code>20480<\/code>. You can go higher, but remember each connection consumes some memory.<\/li>\n<li>Consider adding <code>multi_accept on;<\/code> in the <code>events<\/code> block. 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.<\/li>\n<\/ul>\n<pre><code class=\"language-nginx\"># \/etc\/nginx\/nginx.conf\n\nuser  nginx;\nworker_processes  auto; # Set to &#039;auto&#039; or the number of CPU cores (e.g., 4, 8)\n\nerror_log  \/var\/log\/nginx\/error.log warn;\npid        \/run\/nginx.pid;\n\nevents {\n    worker_connections  20480; # Increase this value significantly (e.g., 10240, 20480, 40960)\n    multi_accept        on;    # Optional: Enable multiple connection accepts per worker\n}\n\nhttp {\n    include       \/etc\/nginx\/mime.types;\n    default_type  application\/octet-stream;\n\n    # ... other http directives ...\n}\n<\/code><\/pre>\n<\/li>\n<li><p><strong>Test Nginx configuration:<\/strong><\/p>\n<pre><code class=\"language-bash\">sudo nginx -t\n<\/code><\/pre>\n<p>Ensure you see <code>syntax is ok<\/code> and <code>test is successful<\/code>.<\/p>\n<\/li>\n<li><p><strong>Reload Nginx service:<\/strong><\/p>\n<pre><code class=\"language-bash\">sudo systemctl reload nginx\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<blockquote class=\"important\"><p>The total number of concurrent connections Nginx can theoretically handle is <code>worker_processes * worker_connections<\/code>. Ensure this value is adequate for your anticipated peak traffic but also mindful of your server&#039;s RAM and CPU resources. A common guideline is to set <code>worker_connections<\/code> to at least <code>2 * UlimitNOFILE<\/code> to account for both client and upstream connections.<\/p>\n<\/blockquote>\n<h4>3. Increase System-wide File Descriptor Limits (ulimit)<\/h4>\n<p>The Nginx process&#039;s file descriptor limit must be equal to or greater than its <code>worker_connections<\/code> setting. We&#039;ll modify the Systemd service unit for Nginx to achieve this.<\/p>\n<ol>\n<li><p><strong>Create or edit the Nginx Systemd override file:<\/strong><\/p>\n<pre><code class=\"language-bash\">sudo systemctl edit nginx\n<\/code><\/pre>\n<p>This will open a file like <code>\/etc\/systemd\/system\/nginx.service.d\/override.conf<\/code>.<\/p>\n<\/li>\n<li><p><strong>Add the <code>LimitNOFILE<\/code> directive:<\/strong>\nAdd the following lines to the file, setting <code>LimitNOFILE<\/code> to a value higher than your <code>worker_connections<\/code> (e.g., <code>65536<\/code> or <code>131072<\/code>).<\/p>\n<pre><code>[Service]\nLimitNOFILE=65536\n<\/code><\/pre>\n<\/li>\n<li><p><strong>Save and exit.<\/strong><\/p>\n<\/li>\n<li><p><strong>Reload the Systemd daemon:<\/strong><\/p>\n<pre><code class=\"language-bash\">sudo systemctl daemon-reload\n<\/code><\/pre>\n<\/li>\n<li><p><strong>Restart Nginx to apply changes:<\/strong><\/p>\n<pre><code class=\"language-bash\">sudo systemctl restart nginx\n<\/code><\/pre>\n<\/li>\n<li><p><strong>Verify the new <code>ulimit<\/code> for the Nginx process:<\/strong><\/p>\n<pre><code class=\"language-bash\">cat \/proc\/$(sudo systemctl show --property MainPID nginx | cut -d= -f2)\/limits | grep &#039;Max open files&#039;\n<\/code><\/pre>\n<p>The <code>soft<\/code> and <code>hard<\/code> limits should now reflect the <code>LimitNOFILE<\/code> you set.<\/p>\n<\/li>\n<\/ol>\n<blockquote class=\"warning\"><p>While increasing <code>LimitNOFILE<\/code> allows Nginx to handle more connections, setting it excessively high without sufficient RAM can lead to memory exhaustion and system instability. Start with <code>65536<\/code> or <code>131072<\/code> and monitor your server&#039;s performance.<\/p>\n<\/blockquote>\n<h4>4. Tune Kernel TCP Backlog Parameters<\/h4>\n<p>Adjusting kernel parameters can help the system handle bursts of new connections more gracefully.<\/p>\n<ol>\n<li><p><strong>Create or edit a custom <code>sysctl<\/code> configuration file:<\/strong><\/p>\n<pre><code class=\"language-bash\">sudo vi \/etc\/sysctl.d\/90-custom.conf\n<\/code><\/pre>\n<p>(You can also use <code>\/etc\/sysctl.conf<\/code>, but <code>.d<\/code> files are cleaner for custom settings).<\/p>\n<\/li>\n<li><p><strong>Add or modify the following parameters:<\/strong><\/p>\n<pre><code class=\"language-sysctl\"># Maximum number of connections that can be queued for a listening socket\nnet.core.somaxconn = 65535\n\n# Maximum number of SYN requests that the kernel will keep in memory\nnet.ipv4.tcp_max_syn_backlog = 8192\n\n# Allow reusing sockets in TIME_WAIT state for new connections (can help with port exhaustion)\nnet.ipv4.tcp_tw_reuse = 1\n\n# Reduce TIME_WAIT state duration (for faster socket cleanup)\nnet.ipv4.tcp_fin_timeout = 30\n<\/code><\/pre>\n<\/li>\n<li><p><strong>Save and exit.<\/strong><\/p>\n<\/li>\n<li><p><strong>Apply the <code>sysctl<\/code> changes:<\/strong><\/p>\n<pre><code class=\"language-bash\">sudo sysctl -p \/etc\/sysctl.d\/90-custom.conf\n<\/code><\/pre>\n<p>(Or <code>sudo sysctl -p<\/code> if you edited <code>\/etc\/sysctl.conf<\/code>).<\/p>\n<\/li>\n<li><p><strong>Verify the new kernel parameters:<\/strong><\/p>\n<pre><code class=\"language-bash\">sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog net.ipv4.tcp_tw_reuse net.ipv4.tcp_fin_timeout\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<blockquote><p><code>net.core.somaxconn<\/code> affects the <code>listen<\/code> directive&#039;s <code>backlog<\/code> parameter in Nginx. <code>net.ipv4.tcp_max_syn_backlog<\/code> is 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.<\/p>\n<\/blockquote>\n<h4>5. Monitor and Optimize<\/h4>\n<p>After implementing these changes, continuous monitoring is crucial to ensure stability and optimal performance.<\/p>\n<ul>\n<li><strong>Monitor Nginx error logs:<\/strong> Keep an eye on <code>\/var\/log\/nginx\/error.log<\/code> for any new connection-related errors.<\/li>\n<li><strong>System resource monitoring:<\/strong> Use tools like <code>atop<\/code>, <code>htop<\/code>, <code>dstat<\/code>, or <code>grafana\/prometheus<\/code> to monitor CPU, memory, and network usage.<\/li>\n<li><strong>Network statistics:<\/strong><ul>\n<li>Check for connections in various states: <code>netstat -nat | awk &#039;{print $NF}&#039; | sort | uniq -c | sort -nr<\/code><\/li>\n<li>Summarize network statistics: <code>ss -s<\/code><\/li>\n<\/ul>\n<\/li>\n<li><strong>Nginx Stub Status Module:<\/strong> If enabled, monitor Nginx&#039;s active connections and requests per second:<pre><code class=\"language-bash\">curl -s http:\/\/localhost\/nginx_status\n<\/code><\/pre>\n(Requires <code>stub_status<\/code> to be enabled in your Nginx configuration, e.g., in a server block: <code>location \/nginx_status { stub_status on; allow 127.0.0.1; deny all; }<\/code>).<\/li>\n<li><strong>Further Nginx Optimization:<\/strong><ul>\n<li>Consider <code>keepalive_timeout<\/code> and <code>keepalive_requests<\/code> if your application benefits from persistent connections.<\/li>\n<li>Optimize proxy buffering settings (<code>proxy_buffering<\/code>, <code>proxy_buffers<\/code>, <code>proxy_buffer_size<\/code>) if Nginx is a reverse proxy.<\/li>\n<li>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.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>By systematically adjusting Nginx configuration and underlying OS limits, you can significantly improve your server&#039;s ability to handle high concurrent connections, ensuring a more stable and responsive web service.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Resolve Nginx connection limit errors on CentOS Stream &amp; Rocky Linux. Learn to tune worker_connections, file descriptors, and kernel parameters for high traffic.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[242,55,23,172,201,56,6,241],"class_list":["post-89","post","type-post","status-publish","format-standard","hentry","category-web-server","tag-centos-stream","tag-nginx","tag-performance","tag-rocky-linux","tag-sysctl","tag-systemd","tag-troubleshooting","tag-worker_connections"],"_links":{"self":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts\/89","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/comments?post=89"}],"version-history":[{"count":2,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts\/89\/revisions"}],"predecessor-version":[{"id":337,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts\/89\/revisions\/337"}],"wp:attachment":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/media?parent=89"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/categories?post=89"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/tags?post=89"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}