PAM: limit system resources
PAM (Pluggable Authentication Modules) does not only do authentication: the pam_limits module caps system resources per user and per group. Without limits, a process can eat all the RAM, all the file descriptors, all the process slots: that is the fork bomb, or simply a process that leaks memory.
The limits.conf file
# /etc/security/limits.conf
# <domain> <type> <item> <value>
# Cap processes for all users
* soft nproc 2048
* hard nproc 4096
# Cap open file descriptors
* soft nofile 1024
* hard nofile 4096
# Cap memory (in KB)
* soft as 1048576
* hard as 2097152
# For the backup group: more open files
@backup soft nofile 8192
@backup hard nofile 16384
# For root: no limit
root soft nproc unlimited
root hard nproc unlimited
soft: the current limit (the process can raise it up to the hard limit)hard: the maximum limit (the process cannot exceed it, even with ulimit -Hn)*: all users@group: a Linux grouproot: the root user
The limits.conf items
| item | what it caps |
|---|---|
nproc | the number of processes |
nofile | the number of open file descriptors |
as | memory (address space) in KB |
rss | resident memory in KB (old, replaced by as) |
cpu | CPU time in minutes |
maxlogins | the number of simultaneous sessions |
core | the size of core dumps |
Checking the limits
ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
max nice (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 4096
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 8192
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 2048
virtual memory (kbytes, -v) unlimited
ulimit -n shows the file descriptor limit: 1024 by default, which is insufficient for a web server or a database. 4096 or 16384 is the minimum for a server.
The nofile case
The nofile is the most commonly hit limit: a web server opens one fd per connection, a database opens several per query and the 1024 cap arrives fast. The fix is in limits.conf:
www-data soft nofile 8192
www-data hard nofile 16384
Then the web process (Apache, nginx) must be restarted for the new limit to apply. PAM limits only apply to new sessions (login, ssh, su), not to running processes.
What PAM limits does not do
PAM limits cap resources PER LOGIN SESSION. A process launched by cron, by a daemon (init), or by an orchestrator does not go through PAM: it inherits the limits of the process that launched it. To cap a daemon’s resources, use ulimit in the launch script.
[edit: 2026] PAM limits is still the standard mechanism to cap resources per user at login. systemd has added LimitNOFILE, LimitNPROC, LimitAS in unit files (the modern mechanism for daemons) and cgroups cap at the container or service level. The 1024 default nofile has been raised to 1048576 in modern distributions (systemd default), but PAM limits remain relevant for interactive sessions and SSH connections. The fork bomb remains the most visual demonstration of why limits exist: :(){ :|:& };: and the system is dead if nproc is not capped.