Shell builtins · bash builtin
ulimit
Show or set per-process resource limits such as open files, core size and stack size.
ulimit [-HS] [-a | -n | -c | -f | -s | -u | -v | -t ...] [LIMIT]
ulimit is a shell builtin that reads and changes the resource limits of the shell, which
every command started from it inherits. The one people meet most is -n, the maximum number of
open files (and sockets) per process: the "Too many open files" error from a busy server or a
big build is that limit being hit. Others cap core dump size (-c), file size (-f), stack
size (-s), CPU seconds (-t) and the number of processes (-u).
Each limit has two values. The soft limit is what is enforced; the hard limit is the
ceiling the soft limit may be raised to. Any user can lower either or raise the soft limit up to
the hard one; only root can raise a hard limit, and lowering it is a one-way trip for that
shell. Without -S or -H, ulimit shows the soft value and sets both.
It has to be a builtin: a separate program could only change its own limits, which would vanish
when it exited. Changes last for the current shell and its children, so the usual pattern is to
run ulimit in a subshell or at the top of a wrapper script. Permanent, system-wide limits live
in /etc/security/limits.conf (for login sessions) or in a systemd unit's LimitNOFILE= and
friends (for services).
Examples
Show the open-files limit
ulimit -n
1024
1024 is the soft limit most Linux systems start with. A process that tries to open file
number 1025 gets EMFILE, "Too many open files".
Show the soft and hard limits separately
echo "soft: $(ulimit -Sn) hard: $(ulimit -Hn)"
soft: 1024 hard: 524288
The hard limit here is 524288, so this user can raise the soft limit a long way without root.
List every limit
ulimit -a | head -n 12
real-time non-blocking time (microseconds, -R) unlimited core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 1029519 max locked memory (kbytes, -l) 8192 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0
-a prints each limit with its unit and the option letter that changes it. Trimmed to the
first twelve lines with head here.
Raise the open-files limit for one command
(ulimit -n 4096; echo "inside: $(ulimit -n)")
echo "outside: $(ulimit -n)"
inside: 4096 outside: 1024
The parentheses run a subshell, so the raised limit applies only there and to anything it starts. The parent shell keeps 1024. Wrapping a server's start command like this is a common quick fix.
Try to go above the hard limit
ulimit -n $(( $(ulimit -Hn) + 1 ))
/bin/bash: line 1: ulimit: open files: cannot modify limit: Operation not permitted
Raising past the hard limit needs root, so a normal user gets Operation not permitted and
status 1.
Lower a hard limit and find you cannot undo it
ulimit -Hn 2048
echo "hard now: $(ulimit -Hn)"
ulimit -Hn 4096
hard now: 2048 /bin/bash: line 3: ulimit: open files: cannot modify limit: Operation not permitted
Lowering a hard limit is allowed, raising it back is not, even for the same user in the same shell. Only a new session (or root) gets the old ceiling back.
Check and disable core dumps
echo "core limit: $(ulimit -c)"
ulimit -c 0
echo "core limit now: $(ulimit -c)"
core limit: unlimited core limit now: 0
A limit of unlimited allows full core dumps when a program crashes; 0 disables them. Many
distributions default to 0 for login shells, and debugging a crash starts with
ulimit -c unlimited. Where the core goes is decided separately by the kernel's
core_pattern.
Cap the size of files a command can write
(ulimit -f 1; head -c 10000 /dev/zero > big.bin)
echo "status: $?"
ls -l big.bin
/bin/bash: line 1: 3702 File size limit exceeded(core dumped) head -c 10000 /dev/zero > big.bin status: 153 -rw-r--r-- 1 dev dev 1024 Oct 31 20:21 big.bin
-f counts in 1024-byte blocks, so the limit is 1 KiB. The write past it raises SIGXFSZ,
which kills head; bash reports the signal and the status is 128 + 25 = 153. Core dumps are
allowed in this sandbox, hence (core dumped). The file stops at exactly 1024 bytes.
Show the stack size limit
ulimit -s
ulimit -Hs
8192 unlimited
The soft stack limit is 8192 KiB (8 MiB), the usual Linux default. Deeply recursive programs that crash with a segmentation fault sometimes need it raised.
Inspect the limits of a running process
prlimit --pid $$ --nofile --core
RESOURCE DESCRIPTION SOFT HARD UNITS NOFILE max number of open files 1024 524288 files CORE max core file size unlimited unlimited bytes
ulimit only sees the current shell. util-linux prlimit reads (and, with permission,
changes) the limits of any process by PID; $$ here is the shell itself. For a quick look,
cat /proc/PID/limits shows the same table.
Common pitfalls
Raising
ulimit -nin your shell and expecting a running service to pick it up. Limits are inherited at process start; restart the service, and for systemd services setLimitNOFILE=in the unit, since/etc/security/limits.confdoes not apply to them.Running
ulimit -n 65535in a script that is executed (not sourced) and then checking the limit in your terminal. The change died with the script's shell.Setting a limit without
-Sand locking yourself out of raising it again: plainulimit -n 2048sets the hard limit too. Useulimit -Snwhen you only want to adjust the soft value.Reading
-f,-cand-svalues as bytes. Bash counts them in 1024-byte blocks or kibibytes (512-byte blocks for-p);ulimit -ashows each unit.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
ulimitis a shell builtin, so its options depend on the shell rather than the OS. POSIX only requires-f; bash and zsh support the full set on both Linux and macOS, while dash (/bin/shon Debian) supports fewer letters.macOS has historically given shells a low soft open-files limit (256) and enforces a separate system-wide cap, shown by
launchctl limit maxfiles; checkulimit -nthere before assuming Linux defaults.
Options worth knowing
A selection, described in our own words. For the full list, see bash(1).
| Option | What it does |
|---|---|
-S | Use the soft limit. |
-H | Use the hard limit. |
-a | Show all current limits. |
-n N | Maximum number of open file descriptors. |
-c N | Maximum core dump size, in 1024-byte blocks. |
-f N | Maximum size of files written, in 1024-byte blocks. |
-s N | Maximum stack size, in kibibytes. |
-u N | Maximum number of processes for the user. |
-v N | Maximum virtual memory, in kibibytes. |
-t N | Maximum CPU time, in seconds. |
-l N | Maximum locked-in-memory size, in kibibytes. |
-d N | Maximum data segment size, in kibibytes. |
-m N | Maximum resident set size (not enforced by modern Linux). |
-i N | Maximum number of pending signals. |
-q N | Maximum bytes in POSIX message queues. |
-e N | Maximum scheduling priority (nice) value. |
-r N | Maximum real-time scheduling priority. |
-x N | Maximum number of file locks. |
-p | Show the pipe buffer size, in 512-byte blocks (read-only). |
Related
umaskShow or set the mask that removes permission bits from newly created files and directories.execReplace the shell with another program, or, with only redirections, change where the shell's own input and output go.setTurn shell options such as -e, -u, -x and pipefail on or off, and replace the positional parameters.psPrint a snapshot of running processes, with the columns, filters and sort order you choose.