How to set a global nofile limit to avoid "many open files" error?
Categories:
Setting a Global 'nofile' Limit to Prevent 'Too Many Open Files' Errors

Learn how to configure system-wide and user-specific 'nofile' limits on Linux to prevent applications from encountering 'Too many open files' errors, ensuring system stability and performance.
The "Too many open files" error, often seen as EMFILE
or ulimit: open files: cannot modify limit: Operation not permitted
, is a common issue in Linux environments, especially for applications that handle a large number of connections or files. This error indicates that a process has exceeded its allowed number of open file descriptors. While individual processes can have their limits adjusted, a more robust solution often involves setting global or system-wide nofile
limits. This article will guide you through understanding, configuring, and verifying these limits on Linux systems, with a focus on Ubuntu and Upstart-managed services.
Understanding File Descriptors and 'nofile' Limits
In Unix-like operating systems, everything is treated as a file, including network sockets, pipes, and actual disk files. When a program interacts with any of these, it uses a file descriptor (FD). Each process has a limit on the number of FDs it can open simultaneously. This limit is controlled by the nofile
parameter, which can be set at various levels: per-process, per-user, and system-wide. Exceeding this limit can lead to application crashes, service interruptions, and general system instability.
flowchart TD A[Application Starts] --> B{Needs File Descriptor} B --> C{Check Process 'nofile' Limit} C -->|Limit Exceeded| D[Error: "Too Many Open Files"] C -->|Limit OK| E[Open File Descriptor] E --> F{Continue Operations} F --> B D --> G[Application Crash/Failure] subgraph System Limits H[System-wide 'nofile' Limit] I[User-specific 'nofile' Limit] end H --- C I --- C
Flowchart illustrating how file descriptor limits affect an application.
Configuring System-Wide 'nofile' Limits
The primary way to set system-wide nofile
limits is by modifying the /etc/sysctl.conf
file. This file contains kernel parameters that are applied at boot time. The relevant parameter is fs.file-max
, which defines the maximum number of file handles the kernel can allocate. Additionally, you can set default limits for all users and processes via /etc/security/limits.conf
.
# Edit /etc/sysctl.conf
sudo nano /etc/sysctl.conf
# Add or modify the following line:
fs.file-max = 200000
# Apply the changes immediately
sudo sysctl -p
Setting the system-wide maximum number of file handles.
# Edit /etc/security/limits.conf
sudo nano /etc/security/limits.conf
# Add these lines at the end of the file to set default limits for all users
# * represents all users
# soft is the current limit, hard is the maximum limit a user can set for themselves
* soft nofile 65536
* hard nofile 65536
# For a specific user (e.g., 'myuser')
# myuser soft nofile 65536
# myuser hard nofile 65536
Setting default 'nofile' limits for all users via limits.conf
.
/etc/security/limits.conf
, users need to log out and log back in for the changes to take effect. For services, a restart of the service or the entire system might be necessary.Handling Upstart Services (Ubuntu 14.04 and older)
For systems using Upstart (common in Ubuntu 14.04 and older), setting nofile
limits requires a different approach for services. Upstart scripts often run before limits.conf
is fully applied to the service's environment. You can directly specify the limit nofile
directive within the Upstart service configuration file.
# Example Upstart service file: /etc/init/my-service.conf
description "My Awesome Service"
start on runlevel [2345]
stop on runlevel [!2345]
# Set the nofile limit for this specific service
limit nofile 65536 65536
exec /usr/local/bin/my-service-executable
# Restart the service after modifying the file
sudo service my-service restart
Setting 'nofile' limits directly in an Upstart service configuration file.
LimitNOFILE
.Verifying 'nofile' Limits
After making changes, it's crucial to verify that the new limits have been applied correctly. You can check the system-wide maximum, the current user's limits, and the limits of a running process.
1. Check System-Wide Maximum
To see the kernel's maximum allowed file handles, use the sysctl
command:
2. Check Current User's Limits
To view the nofile
limits for your current shell session, use the ulimit
command:
3. Check a Specific Process's Limits
To check the limits of a running process, you need its Process ID (PID). First, find the PID (e.g., using pgrep
or ps aux
), then inspect its /proc/<PID>/limits
file:
sysctl fs.file-max
Command to check the system-wide maximum file handles.
ulimit -n
Command to check the current user's 'nofile' limit.
# Find the PID of your process (replace 'my-service' with your actual service name)
PID=$(pgrep my-service)
# Check the limits for that PID
cat /proc/$PID/limits
Commands to check the 'nofile' limits for a specific running process.