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.
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
| Symptom | Cause | Fix |
|---|---|---|
| Configuration test fails | Syntax error in nginx.conf | Check syntax with sudo nginx -t and review error messages |
| Still getting worker_connections warnings | Values still too low for traffic | Increase worker_connections or add more worker processes |
| Nginx won't start after changes | File descriptor limits too low | Increase system limits in /etc/systemd/system/nginx.service.d/limits.conf |
| High memory usage after changes | Too many worker processes | Reduce worker_processes to match CPU cores |
| Status endpoint returns 404 | Status configuration not enabled | Check site is enabled and stub_status module is available |
| Performance degraded | Worker processes exceeds CPU cores | Set worker_processes to auto or CPU core count |
Next steps
- Configure NGINX reverse proxy with SSL termination and load balancing for high availability
- Monitor system resources with Netdata real-time performance dashboard
- Configure NGINX load balancing with health checks and automatic failover
- Set up Nginx performance monitoring with Prometheus and Grafana
- Configure Nginx caching strategies for high-traffic applications