What is the "Too many open files" error?
The "Too many open files" error in Linux occurs when a process (or the system as a whole) exceeds the maximum number of file descriptors it is allowed to open. In Unix-like systems, everything is a file: regular files, directories, sockets, pipes, and even hardware devices. Each open connection, each loaded library, and each network socket consumes a file descriptor. The kernel imposes limits to prevent a single process from exhausting system resources.
When a program attempts to open a new file or socket but has already reached its per-process limit or the system-wide limit, the kernel returns the error EMFILE (too many open files for the process) or ENFILE (too many open files for the system). This error often surfaces in servers (web, database, or application servers) that handle many concurrent connections, or in tools that watch file system changes (like inotify).
Why It Matters
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →Ignoring this error can lead to:
- Application crashes or hangs
- Denial of service (unable to accept new connections)
- Data loss if the program fails to write to log files
- Performance degradation as the system struggles to manage file descriptors
For developers running high-traffic services or processing large numbers of files, understanding and properly configuring file descriptor limits is essential for reliability and scalability.
How to Diagnose the Problem
Before fixing, you must identify the source. Use the following commands:
Check current limits for your shell/process
ulimit -a
Look for the line open files – typically (-n) 1024 for regular users and higher for root.
Check how many file descriptors a specific process is using
lsof -p <PID> | wc -l
Replace <PID> with the process ID. To find the PID of a process:
ps aux | grep your_process_name
Check system-wide file descriptor usage
cat /proc/sys/fs/file-nr
The output shows three numbers: allocated file handles, unused handles, and maximum file handles (file-max). If the first number approaches the third, you are near the system-wide limit.
View current system-wide maximum
cat /proc/sys/fs/file-max
Identify which process is consuming the most descriptors
for pid in /proc/[0-9]*; do
count=$(ls -l "$pid"/fd 2>/dev/null | wc -l)
if [ "$count" -gt 0 ]; then
echo "$(basename $pid): $count"
fi
done | sort -t: -k2 -rn | head -10
How to Fix It
There are several levels at which you can increase the limit:
1. Temporary increase for the current shell session
Use ulimit to set a higher soft limit. This applies only to the current shell and its child processes.
ulimit -n 4096
To set both soft and hard limits (requires root or appropriate privileges):
ulimit -n 65535
2. Permanent increase per user via /etc/security/limits.conf
Edit the file (requires root):
sudo nano /etc/security/limits.conf
Add lines like these (replace your_user with the actual username or use * for all users):
your_user soft nofile 65535
your_user hard nofile 65535
After saving, the user must log out and log back in (or restart the service) for changes to take effect. Verify with ulimit -n.
3. System-wide limit increase
The kernel parameter fs.file-max controls the maximum number of file handles the entire system can allocate. To see the current value:
cat /proc/sys/fs/file-max
To change it temporarily:
sudo sysctl -w fs.file-max=200000
To make it permanent, add to /etc/sysctl.conf or a file in /etc/sysctl.d/:
fs.file-max = 200000
Apply with sudo sysctl -p.
4. Increase per-process limit for a specific service (systemd)
If your application runs under systemd, set the limit in its unit file:
sudo systemctl edit your_service
Add:
[Service]
LimitNOFILE=65535
Then reload systemd and restart the service:
sudo systemctl daemon-reload
sudo systemctl restart your_service
5. Increase limits for a Docker container
When running containers, you can pass limits via docker run:
docker run --ulimit nofile=65535:65535 your_image
Or in a Docker Compose file:
services:
your_service:
ulimits:
nofile:
soft: 65535
hard: 65535
Best Practices
- Monitor proactively: Set up alerts when file descriptor usage exceeds a threshold (e.g., 80% of the limit). Use tools like Prometheus with the
node_exporterorprocess_exporter. - Close file descriptors in code: Ensure your application properly closes files, sockets, and database connections after use. Use try-with-resources in Java, context managers in Python, or RAII in C++.
- Set appropriate limits, not unlimited: Avoid setting extremely high values (e.g., 1,000,000) unless your system has enough memory. Each file descriptor consumes kernel memory (~1-2 KB). Calculate a safe maximum based on your RAM and typical workload.
- Use connection pooling: For network services, reuse connections instead of opening new ones. This reduces the number of open sockets.
- Separate limits per user/service: Use
limits.confor systemd unit overrides to give different processes different limits. A database server may need 100k descriptors, while a simple script only needs 1024. - Check systemd default limits: Some distributions set low default limits for user sessions via
/etc/systemd/system.confand/etc/systemd/user.conf. You can adjustDefaultLimitNOFILE=there. - Test after changes: Always verify with
ulimit -nor by checking the process's/proc/<PID>/limitsfile.
Conclusion
The "Too many open files" error is a common but solvable problem in Linux environments. By understanding the difference between per-process and system-wide limits, and by using the diagnostic tools described in this tutorial, you can quickly pinpoint the bottleneck. Applying the appropriate fix—whether temporary via ulimit, permanent via limits.conf, or system-wide via sysctl—will restore normal operation. Following best practices like monitoring, proper resource cleanup in code, and setting realistic limits will help prevent the error from recurring. With these techniques, you can build robust applications that gracefully handle high concurrency and large numbers of file operations.