Solving the 'Too Many Open Files' Error on Linux

intermediate🐧 Linux2026-03-30| Linux (Ubuntu, Debian, CentOS, RHEL), applicable to Nginx, Apache, MySQL, Java, and Node.js applications.

Error Message

Too many open files
#linux-admin#ulimit#devops#performance

The Error

It usually hits when your traffic spikes: your Nginx server stops accepting connections, or a Java microservice suddenly crashes. Your logs show a blunt message: Too many open files. This happens because the process tried to open more resources than the operating system allows. Linux treats almost every I/O resource—including network sockets, database connections, and pipes—as a file. Each of these consumes a "File Descriptor" (FD).

Too many open files

Why this happens

Linux imposes safety limits to prevent a single buggy process from eating up all system memory. By default, many distributions set a limit of just 1,024 files per process. This is far too low for a modern web server or database. There are two layers to these limits:

  • Soft Limit: This is the current limit enforced by the kernel. A process can increase its own soft limit up to the hard limit value.
  • Hard Limit: This acts as a physical ceiling. Only a user with root privileges can increase the hard limit.

Step 1: Check Your Current Limits

Start by identifying what your system currently allows. Run these commands as the specific user running your application (e.g., www-data or mysql):

# View the soft limit
ulimit -Sn

# View the hard limit
ulimit -Hn

To see the maximum number of files the entire operating system can handle across all processes, run:

cat /proc/sys/fs/file-max

Step 2: Increase Limits for Users (Permanent)

If you run applications manually or via cron, you need to edit the /etc/security/limits.conf file. This change is permanent and survives system reboots.

sudo nano /etc/security/limits.conf

Add these lines to the bottom of the file. We recommend 65535 for most production workloads. Replace * with a specific username if you want to restrict the change:

*    soft    nofile    65535
*    hard    nofile    65535

Important: You must log out and log back in for these changes to take effect for your user session.

Step 3: Fix for Systemd Services

Standard configuration files like limits.conf often don't apply to services managed by systemd (such as Nginx, MySQL, or Node.js apps). For these, you must specify the limit in the service's own configuration.

Create an override file for your specific service:

sudo systemctl edit myservice.service

In the editor, insert the following lines:

[Service]
LimitNOFILE=65535

Save the file and exit. Now, tell systemd to reload the configuration and restart your application:

sudo systemctl daemon-reload
sudo systemctl restart myservice.service

Step 4: Increase System-wide Limits

High-concurrency servers handling millions of requests might hit the kernel's global limit. If /proc/sys/fs/file-max is low, you can increase it by editing /etc/sysctl.conf:

sudo nano /etc/sysctl.conf

Add or update the following parameter to allow 2 million open files:

fs.file-max = 2097152

Apply the new kernel settings immediately without rebooting:

sudo sysctl -p

How to Verify the Fix

Never assume a configuration change worked without checking the live process. Find the Process ID (PID) of your application and inspect its actual runtime limits:

# Find the PID (e.g., for Nginx)
pgrep nginx

# Check the limits for that specific PID
cat /proc/<PID>/limits | grep "Max open files"

The output should now reflect your new limit (e.g., 65535).

Troubleshooting Tips

Identify a File Descriptor Leak

If the error returns after a few days despite high limits, your code likely has a leak. This happens when an app opens database connections or files but forgets to close them. Use lsof to investigate what the process is holding:

# Count exactly how many files a PID has open right now
sudo lsof -p <PID> | wc -l

# See the specific files or sockets being held
sudo lsof -p <PID>

The PAM Requirement

If limits.conf changes aren't working, ensure your system is actually loading the limits module. Check /etc/pam.d/common-session and verify this line isn't commented out:

session required pam_limits.so

Related Error Notes