prlimit: Change a Running Process's ulimit Without a Restart

2026-06-28

The scenario: a long-running daemon starts spitting too many open files. You can't restart it — it has state, sessions, in-flight requests. ulimit only affects the current shell. Editing the systemd unit requires a restart. /proc/<pid>/limits is read-only. Stuck?

Not if you know about prlimit, which hides in the util-linux package on every modern Linux box. It wraps the prlimit(2) syscall added in 2.6.36 — the one that finally let you read and modify the rlimits of an arbitrary PID.

Inspect a running process:

$ prlimit --pid 12345
RESOURCE   DESCRIPTION                       SOFT      HARD UNITS
AS         address space limit          unlimited unlimited bytes
CORE       max core file size                   0 unlimited bytes
CPU        CPU time                     unlimited unlimited seconds
DATA       max data size                unlimited unlimited bytes
NOFILE     max number of open files          1024      4096
NPROC      max number of processes           7831      7831
STACK      max stack size                 8388608 unlimited bytes
...

Already nicer than grepping through /proc/<pid>/limits. But the real trick — change them live, no restart, no LD_PRELOAD, no gdb attach:

$ sudo prlimit --pid 12345 --nofile=65536:65536

The next open() call in that process just works. The daemon doesn't know anything happened.

It also doubles as an inline ulimit for new commands — useful for ad-hoc sandboxing without writing a systemd unit:

$ prlimit --as=1G --core=0 --nofile=4096 ./build.sh

Caps address space to 1 GB, disables core dumps, sets the open-file limit, then exec's the script.

Why this beats the alternatives:

A real production scenario: SSH onto a box where Postgres is logging "too many open files". cat /proc/$(pidof postgres)/limits shows NOFILE=1024. A restart drops every connection. Instead:

$ sudo prlimit --pid $(pidof -s postgres) --nofile=65536:65536

Bleeding stopped. Then go fix the unit file so it survives the next reboot.

The full list of limits it speaks: CPU time, file size, data, stack, core size, RSS, NPROC, NOFILE, locked memory, address space (AS), file locks, pending signals, msgqueue size, nice ceiling, RT priority, RT runtime. Almost all of those are essentially unreachable from userland unless you know prlimit exists.

Caveats worth knowing:

Key Takeaway: ulimit manages your shell's children; prlimit manages any PID on the box — including the one you cannot afford to restart.

All newsletters