System administrators and software engineers regularly face situations where runaway background processes consume excessive CPU time, exhaust available system memory, or monopolise operating system file descriptors. While the classic ulimit shell built-in enables administrators to define resource caps for future commands executed within the current shell session, it cannot alter the limits of already running background processes. The modern prlimit utility solves this challenge by dynamically querying and adjusting soft and hard resource limits for any active process ID (PID) without requiring restarts.
Understanding prlimit and Resource Limits (rlimit)
Linux governs resource consumption using two thresholds for each resource type:
- Soft Limit: The current active threshold enforced by the kernel. When an application exceeds its soft limit, the operating system can issue warning signals (such as
SIGXCPUfor CPU time) or reject further allocation requests. Non-privileged processes can adjust their soft limit up to the ceiling set by the hard limit. - Hard Limit: The absolute maximum ceiling determined by system administrators. Only root users (or processes possessing the
CAP_SYS_RESOURCEcapability) can raise the hard limit.
Part of the util-linux package, prlimit allows you to inspect and modify both boundaries simultaneously on any live process.
Step 1: Identifying the Target Process and Querying Current Limits
Before applying constraints, obtain the Process ID (PID) of the application using pgrep, pidof, or ps:
pgrep -l python3
Suppose your script is running under PID 4821. To inspect its complete matrix of active resource limits, invoke prlimit with the process identifier:
prlimit --pid 4821
The terminal will output a comprehensive table listing every resource parameter—including CPU (CPU time in seconds), AS (address space / virtual memory), NOFILE (maximum open file descriptors), NPROC (maximum user processes), and CORE (core file size)—along with their current soft and hard values.
Step 2: Restricting CPU Time Dynamically
To prevent an intensive processing task or runaway recursive script from dominating system processor cycles indefinitely, assign a maximum cumulative CPU execution time using the --cpu flag:
sudo prlimit --pid 4821 --cpu=300:600
In this syntax, 300 specifies the soft limit (5 minutes of total execution time) and 600 defines the hard limit (10 minutes). When the process hits 300 seconds, the kernel delivers a SIGXCPU signal, allowing the software to perform graceful shutdown routines. If execution reaches the hard limit, the kernel forcefully terminates the process with SIGKILL.
Step 3: Capping Maximum Memory and Address Space
To guard against memory leaks or runaway caching routines crashing critical server infrastructure, constrain the process’s maximum virtual memory using the --as parameter (specified in bytes):
sudo prlimit --pid 4821 --as=1073741824:2147483648
This command establishes a 1 GB soft limit (1073741824 bytes) and a 2 GB hard limit (2147483648 bytes). Subsequent malloc or memory mapping calls attempting to surpass these boundaries will immediately fail, returning standard out-of-memory errors to the application without triggering the global system-wide Out-Of-Memory (OOM) killer.
Step 4: Modifying Maximum Open File Descriptors (NOFILE)
High-concurrency network servers, databases, and microservices often throw “Too many open files” errors when client traffic surges. You can expand the maximum file descriptor limit for a live service on the fly:
sudo prlimit --pid 4821 --nofile=65536:65536
The service immediately inherits the expanded file capacity, permitting additional network sockets and file handles without requiring an application restart or dropping active user connections.
Step 5: Launching New Commands with Pre-Configured Limits
In addition to adjusting running processes, prlimit can execute new binaries under strict resource envelopes directly from scripts:
prlimit --cpu=60 --as=536870912 ./render_batch.sh
This launches the batch script with an enforced 60-second execution deadline and a 512 MB memory threshold, safeguarding workstation stability during automated build and testing pipelines.
Frequently Asked Questions
Do changes made via prlimit survive across process restarts?
No. prlimit applies adjustments directly to the kernel data structures of an active PID. When the application restarts, it will inherit its initial default limits. To persist permanent limits, configure /etc/security/limits.conf or specify LimitNOFILE= and LimitAS= directives in systemd service unit files.
Can a regular non-root user modify resource limits using prlimit?
A non-privileged user can run prlimit against their own processes to inspect limits or lower soft limits. However, elevating hard limits or modifying processes owned by other user accounts requires administrative privileges via sudo.
How does prlimit differ from nice and cpulimit?
nice adjusts scheduling priority without restricting execution capacity, while cpulimit pauses process threads using SIGSTOP and SIGCONT to control percentage usage. Conversely, prlimit enforces absolute kernel-level thresholds on cumulative compute time, memory allocation, and OS primitives.