Friday, 23 April 2021

How to Limit Process at User Level on Linux

 When the system is heavily used, it would be a big challenge for system administrators to manage resources. Ulimit (user limit) is a powerful command which helps to limit resources on your system.

Sometime, but not very often a single user may start too many processes to make the system unstable. To mitigate this we can use ulimit command to limit the number process each user or group can run.

In this tutorial, we learn how to limit the process at user level on Linux.

With ulimit you can set two kinds of limits:

  • Hard limit: This limit is for security purpose. Hard limit can be increased only done by root (ie a non root process cannot go above a hard limit)
  • Soft limit: This limit can be changed by process at any time. A non user can set a limit between (0 and hard limit) for its processes.

Check all current limits

You can check all the limits for the currently logined user.

Run the following ulimit command with -a option:

$ ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 3177
max locked memory       (kbytes, -l) 16384
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
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 3177
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

You can see that there are some unlimited settings. These limits can be changed.

Note: The /proc file-system stores the per-process limits in the file system object located at /proc/4548/limits, where '4548' is the process’s PID or process identifier.

Set ulimit for user

You can use ulimit -u to find max user processes or nproc limit.

$ ulimit -u
3177

You can change max user processes by the following command:

# ulimit -u 3500

If you get any error or unable to change check if you have set any limits in '/etc/security/limits.conf'.

Limits can be set for specific user or group in limits.con file.

If you want to set 'infrateam' to have more process than 'testers' and limit user bob nproc to '60', then set as follows:

@bob          hard    nproc         60
@testers      hard    nproc         100 
@infrateam    hard    nproc         300

Here we set limit to open files using 'nofile' field. As we set soft limit, user will get warnings when they reach the lower limit.

@infrateam   soft   nofile   2000
@infrateam   hard   nofile   3000

Set Ulimit for open file

We can use ulimit command to view the limits open files for each user.

Check the user level open file hard limit

$ ulimit -Hn

4096

Check the user level open file soft limit

# ulimit -Sn

1024

If you want to change the current open file limits (soft or hard) you can update in 'limits.conf' file.

In our example, we will set the maximum number of files to 16384 for all users of the system.

# vim /etc/security/limits.conf
# Then you can add two lines for each limit:
* soft nofile 16384
* hard nofile 16384

Reboot your machine and test the new limits configuration

To check Linux system-wide current maximum number of open file, then run the following command:

# cat /proc/sys/fs/file-max
80786

To change maximum number of open file run following commands:

# sysctl -w fs.file-max=90786

to make it persistent after reboot update in 'sysctl.conf' file

# vi /etc/sysctl.conf
fs.file-max=90786

Set user limit via systemd

Earlier we discussed that we can set limits by editing the /etc/security/limits.conf file but systemd would ignore this file.

Systemd by default reads from '/etc/systemd/system.conf' file. Below are systemd limits equivalent to ulimits.

Directive        ulimit equivalent     Unit
LimitCPU=        ulimit -t             Seconds      
LimitFSIZE=      ulimit -f             Bytes
LimitDATA=       ulimit -d             Bytes
LimitSTACK=      ulimit -s             Bytes
LimitCORE=       ulimit -c             Bytes
LimitRSS=        ulimit -m             Bytes
LimitNOFILE=     ulimit -n             Number of File Descriptors 
LimitAS=         ulimit -v             Bytes
LimitNPROC=      ulimit -u             Number of Processes 
LimitMEMLOCK=    ulimit -l             Bytes
LimitLOCKS=      ulimit -x             Number of Locks 
LimitSIGPENDING= ulimit -i             Number of Queued Signals 
LimitMSGQUEUE=   ulimit -q             Bytes
LimitNICE=       ulimit -e             Nice Level 
LimitRTPRIO=     ulimit -r             Realtime Priority  
LimitRTTIME=     No equivalent

You can set user limit by editing the /etc/systemd/user.conf file.

For example, you can try as below:

vim /etc/systemd/user.conf
DefaultLimitNOFILE=20000

Some services that are started via systemd ignore the /etc/security/limits.conf file. To face this issue, you should set the limits in the service definition file.

You need to update the service file as following:

[Unit]
Description=Some Daemon
After=syslog.target network.target

[Service]
Type=notify
LimitNOFILE=20000
ExecStart=/usr/sbin/somedaemon

[Install]
WantedBy=multi-user.target

Conclusion

In this tutorial, we learned how to use ulimit command to set limit for processes for a user. I hope you enjoyed reading and please leave your suggestions or feedback in the comment section.