Fix nginx worker_connections are not enough warning

Beginner 20 min Apr 17, 2026 14 views
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Resolve Nginx worker_connections warnings by calculating optimal values and tuning worker processes for high-traffic applications. Learn to analyze connection usage and prevent connection exhaustion.

Prerequisites

  • Root or sudo access
  • Nginx installed and running
  • Basic command line knowledge

What this solves

The "worker_connections are not enough" warning appears in Nginx error logs when your server hits connection limits during traffic spikes. This tutorial shows you how to calculate proper worker_connections values, optimize worker processes, and implement monitoring to prevent future connection exhaustion.

Understanding the worker_connections warning

Nginx uses an event-driven architecture where worker processes handle client connections. Each worker process can handle a maximum number of simultaneous connections defined by the worker_connections directive. When this limit is reached, new connections are dropped and the warning appears.

The total connection capacity is calculated as: worker_processes × worker_connections. For reverse proxy scenarios, each client connection may require two connections (client to Nginx, Nginx to backend), effectively halving your capacity.

Note: Connection limits also depend on system file descriptor limits (ulimit) and available memory. Nginx cannot exceed these system-level constraints.

Analyzing current Nginx configuration and load

Check current worker configuration

First, examine your existing Nginx configuration to understand current limits.

sudo nginx -T | grep -E "worker_processes|worker_connections"

Monitor active connections

Check current connection usage to understand your traffic patterns.

sudo ss -tuln | grep :80 | wc -l
sudo ss -tuln | grep :443 | wc -l

Review Nginx error logs

Examine recent error logs to identify when connection limits are hit.

sudo tail -100 /var/log/nginx/error.log | grep "worker_connections"
sudo journalctl -u nginx --since "1 hour ago" | grep "worker_connections"

Check system resource limits

Verify system limits that constrain Nginx connections.

ulimit -n
cat /proc/sys/fs/file-max
sudo systemctl show nginx | grep LimitNOFILE

Calculating optimal worker_connections and worker_processes values

Determine CPU cores and current load

Start by checking your system's CPU configuration and current load patterns.

nproc
lscpu | grep "CPU(s):"
uptime

Calculate worker processes

Set worker_processes to match your CPU cores for optimal performance. For most web servers, this provides the best balance.

echo "Recommended worker_processes: $(nproc)"

Calculate worker connections

Determine appropriate worker_connections based on your traffic and system limits. Use this formula to estimate your needs.

# Check available file descriptors
echo "System file descriptor limit: $(cat /proc/sys/fs/file-max)"
echo "Current ulimit: $(ulimit -n)"

Calculate safe worker_connections (leaving headroom for other processes)

echo "Recommended worker_connections: $(($(ulimit -n) / $(nproc) - 100))"

For reverse proxy setups, divide your calculated value by 2 since each client connection requires two file descriptors. For static file serving, you can use the full calculated value.

Implementing the fix and testing configuration

Backup current configuration

Always backup your working configuration before making changes.

sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup.$(date +%Y%m%d)

Update worker configuration

Edit the main Nginx configuration to update worker settings. Open the configuration file with your preferred editor.

sudo nano /etc/nginx/nginx.conf

Update the events block with your calculated values. Here's an example configuration:

user www-data;
worker_processes auto;  # Or set to your CPU count
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 1024;  # Adjust based on your calculations
    use epoll;
    multi_accept on;
    accept_mutex off;
}

http {
    # Rest of your configuration
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    # Your server blocks
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Test configuration syntax

Verify your configuration changes are syntactically correct before applying them.

sudo nginx -t

Apply configuration changes

Reload Nginx to apply the new configuration without dropping connections.

sudo systemctl reload nginx
sudo systemctl status nginx

Increase system file descriptor limits if needed

If your calculated worker_connections exceeds system limits, increase the file descriptor limits.

sudo mkdir -p /etc/systemd/system/nginx.service.d/
sudo tee /etc/systemd/system/nginx.service.d/limits.conf > /dev/null << 'EOF'
[Service]
LimitNOFILE=65536
EOF

Reload systemd and restart Nginx to apply the new limits.

sudo systemctl daemon-reload
sudo systemctl restart nginx

Monitoring and preventing future connection issues

Enable Nginx status monitoring

Configure the stub_status module to monitor connection usage in real-time.

server {
    listen 127.0.0.1:8080;
    server_name localhost;
    
    location /nginx_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

Enable the status configuration:

sudo ln -s /etc/nginx/sites-available/status /etc/nginx/sites-enabled/status
sudo nginx -t && sudo systemctl reload nginx

Create connection monitoring script

Set up automated monitoring to track connection usage and alert on high usage.

#!/bin/bash

Get current connection stats

STATS=$(curl -s http://127.0.0.1:8080/nginx_status) ACTIVE=$(echo "$STATS" | grep "Active connections" | awk '{print $3}') WORKER_PROCESSES=$(nginx -T 2>/dev/null | grep "worker_processes" | awk '{print $2}' | head -1) WORKER_CONNECTIONS=$(nginx -T 2>/dev/null | grep "worker_connections" | awk '{print $2}' | head -1)

Calculate utilization

if [ "$WORKER_PROCESSES" = "auto" ]; then WORKER_PROCESSES=$(nproc) fi MAX_CONNECTIONS=$((WORKER_PROCESSES * WORKER_CONNECTIONS)) UTILIZATION=$((ACTIVE * 100 / MAX_CONNECTIONS)) echo "$(date): Active: $ACTIVE, Max: $MAX_CONNECTIONS, Utilization: $UTILIZATION%"

Alert if utilization is high

if [ $UTILIZATION -gt 80 ]; then echo "WARNING: High connection utilization ($UTILIZATION%)" logger "Nginx connection utilization high: $UTILIZATION%" fi

Make the script executable and test it:

sudo chmod +x /usr/local/bin/nginx-connection-monitor.sh
/usr/local/bin/nginx-connection-monitor.sh

Set up automated monitoring

Create a systemd timer to run connection monitoring every minute.

[Unit]
Description=Nginx Connection Monitor
After=nginx.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/nginx-connection-monitor.sh
User=nobody
Group=nogroup
[Unit]
Description=Run Nginx Connection Monitor every minute
Requires=nginx-monitor.service

[Timer]
OnCalendar=::00
Persistent=true

[Install]
WantedBy=timers.target

Enable and start the monitoring timer:

sudo systemctl daemon-reload
sudo systemctl enable nginx-monitor.timer
sudo systemctl start nginx-monitor.timer
sudo systemctl status nginx-monitor.timer

Verify your setup

Confirm your changes are working and monitoring is active:

# Check current worker configuration
sudo nginx -T | grep -E "worker_processes|worker_connections"

Verify status endpoint

curl -s http://127.0.0.1:8080/nginx_status

Check monitoring is running

sudo systemctl status nginx-monitor.timer journalctl -u nginx-monitor.service --since "10 minutes ago"

Test connection capacity

echo "Current max connections: $(( $(nginx -T 2>/dev/null | grep worker_processes | awk '{print $2}' | sed 's/auto/'$(nproc)'/') * $(nginx -T 2>/dev/null | grep worker_connections | awk '{print $2}') ))"

Common issues

SymptomCauseFix
Configuration test failsSyntax error in nginx.confCheck syntax with sudo nginx -t and review error messages
Still getting worker_connections warningsValues still too low for trafficIncrease worker_connections or add more worker processes
Nginx won't start after changesFile descriptor limits too lowIncrease system limits in /etc/systemd/system/nginx.service.d/limits.conf
High memory usage after changesToo many worker processesReduce worker_processes to match CPU cores
Status endpoint returns 404Status configuration not enabledCheck site is enabled and stub_status module is available
Performance degradedWorker processes exceeds CPU coresSet worker_processes to auto or CPU core count

Next steps

Running this in production?

Want this handled for you? This works for a single server. When you run multiple environments or need this available 24/7, keeping it healthy is a different job. See how we run infrastructure like this for European teams.

Need help?

Don't want to manage this yourself?

We handle managed cloud infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.