Skip to content

Run a cardano‐node in a dedicated cgroup using systemd

Marcin Szamotulski edited this page Sep 29, 2023 · 2 revisions

When running a node it might be desirable to isolate the cardano-node process from other CPU activities, especially when one wants to measure performance while continuing to do dev work. Here's how to make it work with systemd.

For this we will create a system unit & slice for cardano-node. Unfortunately this doesn't work when using a user units, so everything will need to be run as root.

Although in this tutorial we only limit access to CPU, managment of other resources is also possible, see systemd.resource-control.

The following is the /etc/systemd/system/cardano.slice file . The cardano.slice path matters: it is well explained in systemd.slice man page. This creates a top level slice which branches of directly from the top level system -.slice (see systemd.special).

[Unit]
Description=Cardano Node Slice
Before=slices.target

[Slice]
AllowedCPUs=8-11 20-23

Note: you might want to adjust the AllowedCPUs mask for your use case / CPU.

The following are pretty standard service / socket files, the important part is Slice=cardano.slice in the [Service] section. First /etc/systemd/system/cardano-node.service

[Unit]
Description=cardano-node service
After=network.target
Requires=cardano-node.socket

[Service]
Type=simple
WorkingDirectory=/opt/cardano/node
ExecStart=cardano-node run \
              --topology /opt/cardano/node/topology.json \
              --config /opt/cardano/node/config.json \
              --database-path /opt/cardano/node/db \
              +RTS -N4 -qg -qa -RTS
KillSignal=SIGINT
ExecReload=kill -HUP $MAINPID
KillUserProcess=no
Slice=cardano.slice

[Install]
WantedBy=multi-user.target

and /etc/systemd/system/cardano-node.socket

[Socket]
ListenStream=0.0.0.0:3001
NoDelay=true
ReusePort=true
FreeBind=true

[Socket]
ListenStream=[::]:3001
NoDelay=true
ReusePort=true
BindIPv6Only=true
FreeBind=true

[Socket]
ListenStream=/opt/cardano/node/cardano-node.socket
RemoveOnStop=true

To not let other services use the CPUs:

# run as your $USER
systemctl set-property --runtime user.slice   AllowedCPUs="0-7 12-19"
systemctl set-property --runtime system.slice AllowedCPUs="0-7 12-19"

Now one can start the cardano-node.service:

systemctl start cardano-node.service

And you can see that it's only using dedicated CPUs

cat /proc/$(pidof cardano)/status | grep Cpus_allowed_list
Cpus_allowed_list:      8-11,20-23