Resource exhaustion and runaway processes present substantial operational risks in production Linux environments. A single leaking application can consume thousands of open file descriptors, exhaust memory allocations, or trigger massive core dumps that fill root storage partitions. Traditionally, system administrators configured resource constraints using the shell-builtin ulimit or static configuration files like /etc/security/limits.conf. However, these traditional mechanisms suffer from a significant operational limitation: they only apply to newly instantiated login sessions or child shells. The prlimit utility, integrated into the modern util-linux suite, allows systems engineers to inspect and dynamically modify soft and hard resource limits on running processes without restarting critical daemons.
Understanding Soft Limits, Hard Limits, and System Call Primitives
Linux resource constraints are governed by the prlimit64 kernel system call, which categorises every tunable limit into two distinct values:
- Soft Limit: The actual operational boundary enforced by the kernel. When an unprivileged process exceeds its soft limit, the kernel rejects further allocations (e.g., returning
EMFILEfor “Too many open files”). Unprivileged processes can increase their soft limit up to the ceiling set by the hard limit. - Hard Limit: The absolute ceiling for the soft limit. Once lowered, an unprivileged process cannot raise it back up. Only privileged root processes (or those possessing the
CAP_SYS_RESOURCEcapability) can increase hard limits.
Inspecting Active Resource Limits with prlimit –pid
To view the comprehensive resource limit profile of any running process, supply its Process ID (PID) to prlimit:
prlimit --pid 14205
The command outputs a structured table detailing all sixteen kernel resource categories:
NOFILE:Maximum number of open file descriptors (sockets, pipes, open files).NPROC:Maximum number of processes/threads allowed for the user.AS:Address space limit (virtual memory limit in bytes).CORE:Maximum size of core dump files.MEMLOCK:Maximum locked-in-memory address space (used by databases and real-time encryption caches).STACK:Maximum size of the process stack.
To inspect a single resource limit (such as open files) without displaying the entire table:
prlimit --pid 14205 --nofile
Modifying Resource Limits at Runtime
When an active database, web server, or microservice begins throwing “Too many open files” errors under sudden traffic spikes, restarting the daemon may cause downtime. With prlimit, you can expand limits on the live process:
sudo prlimit --pid 14205 --nofile=65536:65536
The syntax format follows --resource=soft:hard:
- Setting
--nofile=65536:65536establishes both the soft limit and hard limit to 65,536 file descriptors simultaneously. - If you wish to modify only the soft limit while leaving the existing hard ceiling intact, omit the colon and second argument:
sudo prlimit --pid 14205 --nofile=32768
The kernel updates the process structure in memory instantly. The running application can immediately open new file descriptors without crashing or dropping active TCP sockets.
Configuring Core Dump Limits to Prevent Disk Saturation
In high-memory production nodes, a failing process generating an 80 GB core dump can quickly exhaust filesystem space. To prevent a misbehaving daemon from writing core dumps while investigation continues:
sudo prlimit --pid 14205 --core=0:0
Setting the core size to 0 disables kernel core dumping for that specific process immediately.
Inheritance and Child Process Propagation
When you modify a running process using prlimit, any child processes subsequently spawned via fork() and execve() automatically inherit the updated resource limit mask. However, existing child processes that were already running prior to the command retain their original boundaries and must be updated individually or via script iteration.