Linux Ulimit: How to Increase Open File Limits for Servers
Increase open file limit settings on Linux to stop "too many open files" errors. Learn how to tune your nofile limit for high-concurrency performance.
Running a high-traffic web server, especially one handling thousands of concurrent WebSocket connections or heavy database queries, often leads to the dreaded "too many open files" error. It’s a classic bottleneck that stops your application in its tracks, usually when you least expect it.
If you're managing production workloads, you need to understand how to correctly increase the linux ulimit settings. It’s not just about bumping a number; it’s about understanding the layers of the Linux kernel and your init system.
Why the default limit isn't enough
By default, many Linux distributions set the nofile (number of open files) limit to a conservative 1024. For a desktop, that's fine. For a production server running Nginx or a persistent database, it's a disaster waiting to happen. Every open network socket, log file, and database handle counts as a file descriptor. When you hit that cap, your server starts dropping connections or throwing 500 errors.
Before I learned to manage this properly, I remember spending about three hours debugging a production outage where our Nginx performance tuning: Mastering Worker Processes and Buffers efforts were being completely negated by a hard cap on file descriptors. We were trying to scale to 5,000 concurrent users, but the process was hard-limited at 1,024.
How to check your current limits
Before changing anything, check what your system currently allows. You can check the current limits for your user session using:
Bashulimit -n
If you need to check a process already running, you can inspect the /proc filesystem:
Bashcat /proc/<PID>/limits | grep "Max open files"
Increasing the nofile limit permanently
To increase open file limit settings effectively, you must modify the system-wide configuration. Editing ulimit in your current shell only affects that session—it won't survive a reboot or a service restart.
-
Edit the limits configuration file: Open
/etc/security/limits.confwith your text editor of choice. -
Add the following lines: Replace
your_usernamewith the user running your application (e.g.,www-dataornginx).
TEXT* soft nofile 65535 * hard nofile 65535
The asterisk * applies this to all users, but I prefer being explicit to avoid unintended side effects. Using 65535 is a common safe ceiling for most modern Linux kernels.
Applying changes to Systemd services
Even if you update limits.conf, systemd services often ignore these settings. If you’re running a service like Node.js, Go, or a database, you must update the systemd unit file directly.
Run systemctl edit <service_name> and add the following:
INI[Service] LimitNOFILE=65535
After saving, reload the daemon and restart the service:
Bashsystemctl daemon-reload systemctl restart <service_name>
Summary of common limit configurations
| Scope | Method | Purpose |
|---|---|---|
| Current Session | ulimit -n 65535 | Quick temporary test |
| User Wide | /etc/security/limits.conf | Persistent user-level limits |
| Service Specific | systemctl edit | Overrides for background daemons |
| Kernel Wide | /etc/sysctl.conf | Global ceiling via fs.file-max |
Don't forget the kernel ceiling
Sometimes, even after adjusting user limits, you'll hit a wall. That’s because of fs.file-max. This is the global limit for the entire OS. You can check it with:
Bashcat /proc/sys/fs/file-max
If you really need to go beyond 100k+ connections, you might need to increase this in /etc/sysctl.conf:
TEXTfs.file-max = 2097152
Apply it with sysctl -p. If you're building a highly custom environment, I often recommend VPS Server Setup, Deployment & Hardening to ensure these kernel-level parameters are tuned for your specific hardware from day one.
Frequently Asked Questions
What is the difference between soft and hard limits? A soft limit is the value the kernel enforces for the corresponding resource. A hard limit acts as a ceiling for the soft limit. An unprivileged process can only lower its soft limit or raise it up to the hard limit.
Will setting the limit to 1,000,000 cause performance issues? Technically, no. The kernel manages these descriptors efficiently. However, setting an absurdly high limit can hide bugs where your application is leaking file descriptors (e.g., failing to close sockets).
Do I need to reboot after changing limits?
Usually, no. Systemd service changes take effect after a daemon-reload and restart. Changes to limits.conf apply to new login sessions.
I’ve seen engineers panic and set these limits to "unlimited" or millions, only to find out they had a memory leak in their connection pool. Always monitor your actual usage with lsof | wc -l before assuming you need to go higher. If you find your server is still sluggish, look into Linux Sysctl Tuning for High-Performance Docker Networking to see if you're actually hitting network stack bottlenecks instead.