Limit available system resources per user with Systemd and cgroups
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
- Linux Control Groups (cgroups)
- Find Systemd slice units
- Modify slice unit default options
- Apply the changes
- Apply limits to specific slice units
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 likeM
orG
(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
.
If you have any suggestion, feel free to contact me via social media or email.
Latest tutorials and articles:
Featured content: