If your operating system has Systemd installed, you can easily limit available system resources for each user just by editing a few files.

Table of Contents

Systemd “slice” units

“A unit configuration file whose name ends in ‘.slice’ encodes information about a slice unit. A slice unit is a concept for hierarchically managing resources of a group of processes. This management is performed by creating a node in the Linux Control Group (cgroup) tree.” (from systemd.slice(5)).

Linux Control Groups (cgroups)

Linux Control Groups (or cgroups) “allow you to allocate resources — such as CPU time, system memory, network bandwidth, or combinations of these resources — among user-defined groups of tasks (processes) running on a system” (from Red Hat).

Find Systemd slice units

Run systemctl status and, under CGroup you can see how many slice units exist on your system.

$ systemctl status
● mycomputer
    State: running
     Jobs: 0 queued
   Failed: 0 units
    Since: Tue 2022-04-19 17:18:41 CEST; 18h ago
   CGroup: /
           ├─init.scope
           │ └─1 /sbin/init
           ├─system.slice
           ...
           └─user.slice
             └─user-1000.slice
             ...

There will likely be two main slice units: system.slice and user.slice. Inside user.slice there are as many slice units as logged users. Each user slice unit under user.slice has this name structure: user-<UID>.slice.

To get more info about a slice unit, run systemctl status <slice unit>, e.g.: systemctl status user-1000.slice.

$ systemctl status user-1000.slice
user-1000.slice - User Slice of UID 1000
     Loaded: loaded
    Drop-In: /usr/lib/systemd/system/user-.slice.d
             └─10-defaults.conf
     Active: active since Tue 2022-04-19 17:19:39 CEST; 19h ago
     ...

Modify slice unit default options

When you run above command (systemctl status user-1000.slice) you will see a folder path in Drop-in section.

Drop-In: /usr/lib/systemd/system/user-.slice.d
             └─10-defaults.conf

/usr/lib/systemd/system/user-.slice.d/10-defaults.conf defines default cgroup options for each user slice unit. Open this file and you will see something like this:

[Unit]
Description=User Slice of UID %j
Documentation=man:user@.service(5)
After=systemd-user-sessions.service
StopWhenUnneeded=yes

[Slice]
TasksMax=33%

Inside [Slice] you can type system resource limits. You can check https://man.archlinux.org/man/systemd.resource-control.5.en to find all available options, but the most relevant are:

  • MemoryHigh=<bytes>: define the throttling limit on memory usage, you can use suffixes like M or G (MemoryHigh=2G).
  • CPUQuota=<percentage>: assign the CPU time quota to the processes executed on one CPU (CPUQuota=40%).
  • TasksMax=<number>: maximum number of tasks that may be created by the unit. You can type a number or a percentage value (relative to the maximum number of tasks on the system).
  • IPAddressDeny=any: block network access.

Apply the changes

Run systemctl daemon-reload to reload systemd with the new options.

Apply limits to specific slice units

You can also run systemctl set-property <slice unit> <property>=<value> to apply a limit to a specific user or to the global user.slice unit. A new file inside /etc/systemd/system.control/user-<UID>.slice.d/ (or /etc/systemd/system.control/user.slice.d/ for global user slice unit) will be created.

For example:

systemctl set-property user-1002.slice MemoryHigh=1G

will set a RAM usage limit on UID (User ID) 1002. To find a UID , run id <username>.

If you define a limit on user.slice, this will be a global limit because user.slice is the parent of user-<UID>.slice units.

To remove or restore a property, just delete the appropriate file under /etc/systemd/system.control/user-<UID>.slice.d/ (or /etc/systemd/system.control/user.slice.d) and run systemctl daemon-reload.