what is nproc and nofile in ulimits?
Categories:
Understanding nproc and nofile in ulimits for Linux Systems

Explore the critical ulimit parameters, nproc and nofile, their impact on system stability and application performance, especially for demanding services like MongoDB.
In Linux-based systems, ulimit
is a powerful command that allows administrators to control the resources available to processes. Two of the most frequently configured and misunderstood parameters are nproc
(number of processes) and nofile
(number of open files). Misconfiguring these limits can lead to system instability, application crashes, or performance bottlenecks, particularly for resource-intensive applications like databases such as MongoDB. This article will delve into what these parameters mean, why they are important, and how to configure them effectively.
What are nproc and nofile?
The ulimit
command manages various resource limits for processes. These limits can be set per-user, per-group, or system-wide. Understanding nproc
and nofile
is fundamental for system stability and application performance.
nproc
(Number of Processes): This limit defines the maximum number of processes (or threads) that a user can run concurrently. Each process, even a lightweight one, consumes system resources. If a user or an application attempts to spawn more processes than allowed bynproc
, the system will deny the request, often leading to application failure.nofile
(Number of Open Files): This limit specifies the maximum number of file descriptors that a process can have open simultaneously. In Linux, 'everything is a file,' meaning not just actual files on disk, but also network sockets, pipes, and devices are represented as file descriptors. Applications that handle many concurrent connections (like web servers or databases) or interact with numerous files will quickly hit this limit if it's set too low.
flowchart TD A[Application Starts] --> B{Needs Resources?} B -->|Yes| C{Check ulimit -n (nofile)} C -->|Exceeds?| D[Error: Too many open files] C -->|OK| E{Check ulimit -u (nproc)} E -->|Exceeds?| F[Error: Cannot fork/create process] E -->|OK| G[Resource Allocated/Process Created] D --> H[Application Fails/Degrades] F --> H G --> I[Application Runs Successfully]
Flowchart illustrating how nproc and nofile limits impact application resource allocation.
Why are these limits crucial for applications like MongoDB?
Database systems like MongoDB are inherently resource-intensive. They manage numerous connections, read and write to many data files, and often spawn background processes or threads for various tasks (e.g., journaling, replication, query execution). If nproc
or nofile
are set too low, MongoDB can experience severe issues:
nofile
for MongoDB: MongoDB uses file descriptors for:- Data files (e.g.,
WiredTiger.wt
,journal
files) - Network connections (client connections, replica set communication)
- Internal pipes and sockets
If
nofile
is too low, MongoDB might fail to accept new client connections, struggle to open necessary data files, or even crash due to resource exhaustion.
- Data files (e.g.,
nproc
for MongoDB: While MongoDB primarily uses threads, Linux treats threads as processes fornproc
limits. MongoDB can spawn many threads for:- Client request handling
- Background operations (e.g., journaling, replication, data compaction)
- Internal worker threads
If
nproc
is too low, MongoDB might be unable to create new threads, leading to connection failures, slow query performance, or an inability to perform critical background tasks.
nofile
to at least 64000 and nproc
to at least 64000. These values are often recommended by MongoDB documentation as a starting point, but should be adjusted based on actual workload and monitoring.Configuring ulimits: Temporary vs. Permanent
Ulimits can be set temporarily for the current shell session or permanently across reboots. Understanding the difference is key to effective system administration.
Temporary Configuration
To check the current limits for your shell session, use the ulimit -a
command. To set a temporary limit, use ulimit -n
for nofile
and ulimit -u
for nproc
.
These changes only apply to the current shell and any processes launched from it. They will be lost once the shell session ends.
# Check current nofile limit
ulimit -n
# Set temporary nofile limit to 65536
ulimit -n 65536
# Check current nproc limit
ulimit -u
# Set temporary nproc limit to 65536
ulimit -u 65536
Checking and setting temporary ulimits in a bash session.
Permanent Configuration
For persistent changes that survive reboots and apply to specific users or services, you need to edit the /etc/security/limits.conf
file or files within the /etc/security/limits.d/
directory. These files define resource limits for users and groups.
Each line in limits.conf
typically follows this format:
domain type item value
domain
: The user, group, or wildcard (*
for all users,@groupname
for a specific group).type
:soft
(the current limit, which can be increased by the user up to the hard limit) orhard
(the maximum limit, which only root can increase).item
: The resource to limit (e.g.,nofile
,nproc
).value
: The limit value.
After modifying limits.conf
or limits.d/
files, you usually need to log out and log back in for the changes to take effect for user sessions. For system services (like MongoDB), you might need to restart the service or even the system, depending on how the service is started and how it inherits its environment.
# /etc/security/limits.conf or a file in /etc/security/limits.d/ (e.g., 99-mongodb.conf)
# Set hard and soft nofile limits for the 'mongodb' user
mongodb soft nofile 64000
mongodb hard nofile 64000
# Set hard and soft nproc limits for the 'mongodb' user
mongodb soft nproc 64000
mongodb hard nproc 64000
# Alternatively, for all users (use with caution)
# * soft nofile 64000
# * hard nofile 64000
# * soft nproc 64000
# * hard nproc 64000
Example configuration in /etc/security/limits.conf
for the mongodb
user.
pam_limits.so
module is enabled in /etc/pam.d/common-session
or /etc/pam.d/login
for limits.conf
changes to take effect. Without it, your permanent configurations will be ignored.Verifying Limits for a Running Process
To verify the actual limits applied to a running process, you can inspect its /proc/<pid>/limits
file. This is particularly useful for services started by systemd or other init systems, as they might not inherit limits in the same way a direct shell login does.
# Find the PID of the mongod process
PID=$(pgrep mongod)
# Display the limits for the mongod process
cat /proc/$PID/limits
Checking the effective limits for a running mongod
process.