Very often ‘too many open files’ errors occur on high-load Linux servers. It means that a process has opened too many files (file descriptors) and cannot open new ones. In Linux, the maximum open file limits are set by default for each process or user and the values are rather small.
In this article we will learn how to check the current limit on the maximum number of open files in Linux and how to change it for the entire host, individual service or a current session.
‘Too Many Open Files’ Error & Open File Limits in Linux
First of all, let’s see where the ‘too many open files’ error appears. The most often it occurs on the servers with an installed NGINX/httpd web server or a database server (MySQL/MariaDB/PostgreSQL) when reading a large number of logs. For example, when an Nginx web server exceeds the open file limit, you will see an error:
socket () failed (29: Too many open files) while connecting to upstream
Using this command, you can get the maximum number of file descriptors your system can open:
# cat /proc/sys/fs/file-max
The open file limit for a current user is 1024. You can check it as follows:
# ulimit -n
There are two limit types: Hard and Soft. A user can change a soft limit (however, the soft value cannot exceed the hard one). Only a privileged or root user can modify a hard limit value.
To display the soft limit, run this command:
# ulimit –nS
To display the hard limit value:
# ulimit -nH
How to Increase the Max Open File Limit in Linux?
To allow all services open a large number of files, you can change the limits in your Linux OS. To make new settings permanent and prevent their reset after a server or session restart, you must make changes to /etc/security/limits.conf. Add these lines:
* hard nofile 97816 * soft nofile 97816
If you are using Ubuntu, add this line as well:
session required pam_limits.so
This parameter allows to set open files limits after user authentication.
After making any changes, reload the terminal and check the max_open_files value:
# ulimit -n
97816
Increasing the Open File Descriptor Limit per Service
You can change the limit of open file descriptors for a specific service, rather than for the entire operating system. Let’s take apache as an example. Open the service settings using systemctl:
# systemctl edit httpd.service
Add the limits you want, e.g.:
[Service] LimitNOFILE=16000 LimitNOFILESoft=16000
After making the changes, update the service configuration and restart it:
# systemctl daemon-reload
# systemctl restart httpd.service
To make sure if the values have changed, get the service PID:
# systemctl status httpd.service
For example, the service PID is 3724:
# cat /proc/3724/limits | grep "Max open files”
Thus, you have changed the values for the maximum number of open files for a specific service.
How to Set Max Open Files Limit for Nginx & Apache?
When changing the limit on the number of open files for a web server, you also have to change the service configuration file. For example, specify/change the following directive value in the Nginx configuration file /etc/nginx/nginx.conf:
worker_rlimit_nofile 16000
Then restart Nginx.
For apache, create a directory:
# mkdir /lib/systemd/system/httpd.service.d/
Then create the limit_nofile.conf file:
# nano /lib/systemd/system/httpd.service.d/limit_nofile.conf
Add to it:
[Service] LimitNOFILE=16000
Don’t forget to restart httpd.
Change the Open File Limit for the Current Session
To change maximum open file limits for your terminal session, run this command:
# ulimit -n 3000
After closing the terminal and creating a new session, the limits will get back to the original values specified in /etc/security/limits.conf.
To change the general value for the system /proc/sys/fs/file-max, change the fs.file-max value in /etc/sysctl.conf:
fs.file-max = 100000
And apply it:
# sysctl -p
In this article we have learned how to solve the issue when the value of open file descriptor limit in Linux is too small, and discussed some options of changing these limits on the server.
1 comment
Not really sure what ulimit is running on OpenSUSE Leap 15.2, but ulimit-nS fails with -bash: ulimit: S: invalid number (same for -nH)
Correct, for my ulimit implementation, is ulimit -Sn (and -Hn) as it requires the ‘soft’/’hard’ param to be 1st.