Fix Linux 'Too Many Open Files' System-Wide
The Error
Applications start failing with errors like:
Too many open files
java.io.IOException: Too many open files
socket: too many open files
The system or a specific process has exhausted its file descriptor limit. Since Linux treats almost everything as a file (sockets, pipes, actual files), high-traffic services hit this limit frequently.
Root Cause
Linux enforces file descriptor limits at three levels:
- System-wide limit (
fs.file-max) - The absolute maximum number of file descriptors the kernel will allocate. - User-level limit (
ulimit//etc/security/limits.conf) - The maximum per-user, enforced by PAM. - Systemd service limit (
LimitNOFILE) - Per-service override when running under systemd.
The default soft limit is often 1024, which is far too low for database servers, web servers, or any application handling many concurrent connections.
Step-by-Step Fix
1. Check current limits
# System-wide maximum
cat /proc/sys/fs/file-max
# Current system-wide usage
cat /proc/sys/fs/file-nr
# Output: <allocated> <free> <max>
# Current user limits
ulimit -n # soft limit
ulimit -Hn # hard limit
# For a specific running process
cat /proc/<PID>/limits | grep "open files"
2. Increase the system-wide limit
# Temporary (survives until reboot)
sudo sysctl -w fs.file-max=2097152
# Permanent
echo "fs.file-max = 2097152" | sudo tee -a /etc/sysctl.d/99-file-max.conf
sudo sysctl --system
3. Increase user-level limits
Edit /etc/security/limits.conf:
sudo tee -a /etc/security/limits.conf <<EOF
# Increase file descriptor limits
* soft nofile 65535
* hard nofile 65535
root soft nofile 65535
root hard nofile 65535
EOF
Ensure PAM is configured to apply these limits. Check that this line exists in /etc/pam.d/common-session:
session required pam_limits.so
The user must log out and back in for the new limits to take effect.
4. Increase limits for systemd services
For services managed by systemd, user limits from limits.conf may not apply. Override at the service level:
sudo systemctl edit nginx
Add:
[Service]
LimitNOFILE=65535
Then reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart nginx
Verify:
cat /proc/$(pgrep -f nginx | head -1)/limits | grep "open files"
5. Immediate relief for a running process (no restart)
On Linux 4.1+ with kernel support, you can use prlimit to change limits on a running process:
sudo prlimit --pid <PID> --nofile=65535:65535
6. Find the file descriptor leak (if limits are reasonable)
If the limit is already high but still being hit, you may have a file descriptor leak:
# Count open FDs for a process
ls /proc/<PID>/fd | wc -l
# See what files are open
ls -la /proc/<PID>/fd | tail -20
# Or use lsof
lsof -p <PID> | wc -l
lsof -p <PID> | awk '{print $5}' | sort | uniq -c | sort -rn | head
Prevention Tips
- Set high limits in your base image or provisioning scripts. A soft limit of 65535 is a safe default for most production servers.
- Monitor file descriptor usage. Export
/proc/sys/fs/file-nrto your monitoring system and alert at 80% utilization. - Configure application-level limits. Many applications (Nginx, MySQL, Elasticsearch) have their own
max_connectionsorworker_connectionssettings that should align with the OS limit. - Audit for FD leaks. Periodically check long-running processes for steadily increasing FD counts, which indicate a leak in connection or file handling code.
Was this article helpful?
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
Fix SSH 'Connection Refused' After Server Reboot
Diagnose and fix SSH connection refused errors after a Linux server reboot, covering sshd service, firewall rules, port configuration, and host key issues.
Linux Networking Commands: Cheat Sheet
Linux networking commands cheat sheet for troubleshooting — interfaces, routing, DNS lookups, connections, iptables firewalls, and tcpdump packet capture.
Linux Networking & Firewall: Configuration and Troubleshooting
Configure Linux network interfaces, set up iptables/nftables/firewalld rules, troubleshoot connectivity with ss, ip, dig, and tcpdump, and secure your servers.
Linux Performance Troubleshooting: CPU, Memory, Disk, and Network
Diagnose Linux performance bottlenecks with top, htop, vmstat, iostat, sar, iotop, and strace — a systematic approach to finding and fixing issues.
Linux Control Groups (cgroups V2): Limiting CPU And Memory For Production Workloads
If you're running production workloads without cgroup constraints, you're one runaway process away from a bad day. Here's everything you need to configure...
Alpine Linux apk Reference: Package Management, Repositories, and System Administration
A complete reference for Alpine Linux's apk package manager — adding packages, managing repositories, pinning versions, building custom packages, and running Alpine as a minimal server OS.
More in Linux
View all →Alpine Linux for Docker: Building Minimal, Secure Container Images
How to use Alpine Linux as a Docker base image effectively — understanding musl libc compatibility, multi-stage builds, layer optimization, and the security trade-offs versus glibc-based distributions.
openSUSE MicroOS and Transactional Updates: Atomic System Updates with Btrfs Snapshots
How openSUSE's transactional-update and Btrfs snapshot integration enables atomic, rollback-safe system updates — and how MicroOS takes this to a fully immutable, container-optimized OS.
openSUSE and SUSE Linux Enterprise: YaST Administration and zypper Package Management
A practical guide to SUSE Linux administration — using YaST for system configuration, zypper for package management, managing repositories, and understanding the differences between openSUSE Leap, Tumbleweed, and SUSE Linux Enterprise.
RHEL 9 Performance Tuning: tuned, sysctl, and CPU/Memory Optimization
How to tune RHEL 9 performance using tuned profiles, sysctl parameters, CPU governors, NUMA topology, and memory settings — for database servers, web workloads, and latency-sensitive applications.