How to set limits for services in RHEL 7 and systemd

Solution Verified - Updated -

Environment

  • Red Hat Enterprise Linux (RHEL) 7, 8
  • systemd

Issue

How can I set the limits for services started at boot time via systemd?

Limits set in /etc/security/limits.conf or /etc/security/limits.d/*.conf are ignored.

Resolution

A service definition can be extended as described in the systemd.unit(5) man page in the section "Example 2. Overriding vendor settings", and in the Red Hat Enterprise Linux 7 System Administrator's Guide, Section 8.6. Creating and Modifying systemd Unit Files

Using tftp.service as an example, create a new tftp.service.d directory under /etc/systemd/system, and then create a conf file in that directory which extends (or overrides) the settings for the service. In this example, the number of open file descriptors is limited to 500,000.

# mkdir -p /etc/systemd/system/tftp.service.d/
# cat >/etc/systemd/system/tftp.service.d/filelimit.conf <<EOF
[Service]
LimitNOFILE=500000
EOF

The change is applied after reloading the daemon configuration and restarting the service.

# systemctl daemon-reload
# systemctl restart tftp.service

The systemd-delta and systemctl status tftp.service commands both show that the service definition has been extended.

# systemd-delta --type=extended
[EXTENDED]   /usr/lib/systemd/system/tftp.service → /etc/systemd/system/tftp.service.d/filelimit.conf

1 overridden configuration file found.

# systemctl status tftp.service
● tftp.service - Tftp Server
   Loaded: loaded (/usr/lib/systemd/system/tftp.service; indirect; vendor preset: disabled)
  Drop-In: /etc/systemd/system/tftp.service.d
           └─filelimit.conf
  ...

The available limits are described in the following section from the systemd.exec(5) man page:

       LimitCPU=, LimitFSIZE=, LimitDATA=, LimitSTACK=, LimitCORE=, LimitRSS=,
       LimitNOFILE=, LimitAS=, LimitNPROC=, LimitMEMLOCK=, LimitLOCKS=,
       LimitSIGPENDING=, LimitMSGQUEUE=, LimitNICE=, LimitRTPRIO=,
       LimitRTTIME=
           These settings control various resource limits for executed
           processes. See setrlimit(2) for details. Use the string infinity to
           configure no limit on a specific resource.

Important: Some services may have resource limits that cannot be changed in this way. One such example is sendmail which changes the resource limit for the maximum number of open files to 1024 (and can modify other resource limits). It is not possible to change these resource limits for sendmail - they are set explicitly and are not changable via sendmail configuration. This behaviour is not a defect, it is the expected behaviour for programs that manage and set their own resource limits.

Root Cause

Limits defined in /etc/security/limits.conf or /etc/security/limits.d/*.conf are set by pam when starting login session. This is configured by following line from /etc/pam.d/system-auth-ac:

session     required      pam_limits.so

Since daemons started by systemd don't employ pam login session, the limits can be set only in the service unit file.

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

4 Comments

According to the official documentation ( https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Unit_Files.html#sect-Managing_Services_with_systemd-Unit_File_Modify ), the /usr/lib/ file shouldn't be overwritten, but you should create a new one in /etc
Also, if a future software update overwrites your /usr/lib/ service file, you're screwed :)

This "solution" is incorrect.
Create a custom file under /etc/systemd/system/ tested and works

Solution does not work under RHEL 7.2. (although this is also the recommended procedure according to the systemd man pages). Add the LimitNOFILE=XXX directly to the .service file under /usr/lib/systemd/system did work.

I have Veritas cluster running which starts tons of applications thru it and limits are not placed. How can I configure what? Configuring VCS as daemon in systemd is not an option as I need to limit not VCS itself, but applications it starts and controls.