DevOpsil
Nginx
85%
Needs Review

Fix Nginx 'Too Many Open Files' Error

Sarah ChenSarah Chen3 min read

The Error: Too Many Open Files

Nginx starts dropping connections under load. The error log shows:

2026/03/30 09:15:32 [alert] 2847#0: *198234 socket() failed
(24: Too many open files) while connecting to upstream

Or during startup:

nginx: [warn] 2048 worker_connections exceed open file resource limit: 1024

Clients experience refused connections, timeouts, or intermittent 500 errors during traffic spikes.

Root Cause

Every active connection in Nginx requires at least two file descriptors (one for the client socket, one for the upstream or static file). On Linux, processes have a default limit of 1024 open file descriptors. A busy Nginx server with worker_connections 4096 needs at least 8192 file descriptors per worker, but the OS is capping it at 1024.

The limit comes from three layers, and all three must be raised:

  1. Kernel limit (fs.file-max) — system-wide maximum
  2. User limit (ulimit -n) — per-user/per-process maximum
  3. Nginx config (worker_rlimit_nofile) — Nginx's own cap

Step-by-Step Fix

1. Check current limits

# System-wide kernel limit
cat /proc/sys/fs/file-max

# Current open files across the system
cat /proc/sys/fs/file-nr
# Output: 5120  0  2097152  (allocated / free / max)

# Nginx worker process limit
cat /proc/$(pgrep -f 'nginx: worker' | head -1)/limits | grep "open files"
# Max open files  1024  1024  files

# Nginx configuration
nginx -T 2>/dev/null | grep -E 'worker_rlimit_nofile|worker_connections'

2. Increase the kernel limit

# Temporary (until reboot)
sudo sysctl -w fs.file-max=2097152

# Permanent
echo "fs.file-max = 2097152" | sudo tee -a /etc/sysctl.d/99-file-limits.conf
sudo sysctl -p /etc/sysctl.d/99-file-limits.conf

3. Increase per-user limits

Edit /etc/security/limits.conf:

# /etc/security/limits.conf
www-data    soft    nofile    65535
www-data    hard    nofile    65535
root        soft    nofile    65535
root        hard    nofile    65535

For systemd-managed Nginx, override the service unit:

sudo systemctl edit nginx

Add:

[Service]
LimitNOFILE=65535

This creates /etc/systemd/system/nginx.service.d/override.conf.

sudo systemctl daemon-reload
sudo systemctl restart nginx

4. Configure Nginx's own limit

Edit /etc/nginx/nginx.conf:

# Set at the top level, outside any block
worker_rlimit_nofile 65535;

events {
    worker_connections 16384;    # Must be <= worker_rlimit_nofile
    multi_accept on;
    use epoll;
}

A good rule of thumb: worker_rlimit_nofile should be at least 2 * worker_connections.

Test and reload:

sudo nginx -t
sudo systemctl reload nginx

5. Verify the fix

# Check the new limits on the worker process
cat /proc/$(pgrep -f 'nginx: worker' | head -1)/limits | grep "open files"
# Max open files  65535  65535  files

# Monitor file descriptor usage under load
watch -n 1 "ls /proc/$(pgrep -f 'nginx: worker' | head -1)/fd | wc -l"

6. Quick reference: the three layers

LayerSettingFile
Kernelfs.file-max/etc/sysctl.d/99-file-limits.conf
User/ProcessLimitNOFILEsystemctl edit nginx
Nginxworker_rlimit_nofile/etc/nginx/nginx.conf

All three must be aligned. The effective limit is the minimum of the three.

Prevention Tips

  • Set these limits in your provisioning automation (Ansible, Packer, cloud-init) so every new server is configured from day one.
  • Calculate capacity: workers * worker_connections * 2 gives the minimum file descriptors needed. Size worker_rlimit_nofile above that.
  • Monitor with Prometheus: export process_open_fds from the Nginx exporter and alert at 80% of the limit.
  • Use worker_connections wisely — each idle keepalive connection still holds a file descriptor. Set keepalive_timeout to a reasonable value (15-30s).
  • Load test before production to validate limits under realistic traffic patterns.
Share:

Was this article helpful?

Sarah Chen
Sarah Chen

CI/CD Engineering Lead

Automation evangelist who believes no deployment should require a human. I write pipelines, break pipelines, and write about both. Code-first, always.

Related Articles

More in Nginx

View all →

Discussion