Mastering systemd-run: ‘Instant’ CPU and RAM Limits for Linux Scripts

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Running Heavy Scripts Without Crashing Your Server: The systemd-run Solution

Have you ever run a backup script or compressed a folder several dozen GBs in size, only to have your server suddenly ‘freeze’? CPU spikes to 100%, RAM is exhausted, and Nginx starts returning 504 errors. Previously, I often used nice, but it only adjusts priority and cannot truly ‘cap’ actual resources.

On the Ubuntu 22.04 server (4GB RAM) I manage, systemd-run is a real lifesaver for ad-hoc tasks. This tool allows me to command: “This script can only use a maximum of 500MB RAM and 20% CPU”. If it exceeds the threshold, systemd automatically intervenes, keeping core services safe.

Quick Start: Resource Limiting in 30 Seconds

Suppose you need to run a Python data processing script but are afraid it will ‘swallow’ all the RAM. Use the following command structure to limit it to 500MB RAM and 30% of a single CPU core:

sudo systemd-run --scope -p MemoryMax=500M -p CPUQuota=30% python3 heavy_script.py

Breaking down the key parameters:

  • --scope: Runs directly in the current terminal. If you close the terminal, the command stops.
  • -p MemoryMax=500M: Maximum RAM threshold. If exceeded, the process will be ‘killed’.
  • -p CPUQuota=30%: Ensures the process does not occupy more than 30% of total CPU time.

The best part is that systemd creates a transient unit and applies cgroups immediately. You no longer need to manually create .service files like before.

Why systemd-run Outperforms Older Tools?

Many older documents still recommend using ulimit. However, ulimit is difficult to manage for process groups. systemd-run is different; it leverages cgroups (Control Groups). This is the core technology that helps Docker isolate resources effectively.

Differentiating –scope and –unit

Depending on your needs, choose the appropriate execution mode:

  • –scope: Runs in the current shell. You will see the output displayed directly on the screen.
  • –unit: Turns the command into a background service. Perfect for tasks that take several hours.
sudo systemd-run --unit=backup-job -p MemoryMax=1G /usr/local/bin/backup.sh

With --unit, you can safely turn off your computer and go to sleep. Tomorrow morning, just check back with systemctl status backup-job.

The Most Valuable Limit Parameters

Here are the flags I frequently apply in real-world projects:

1. Memory (RAM) Limits

  • MemoryMax: Hard limit. If exceeded, the OOM Killer will intervene immediately.
  • MemoryHigh: Soft limit. When reached, the system will force the process to release memory or slow it down rather than killing it outright.
sudo systemd-run --scope -p MemoryHigh=800M -p MemoryMax=1G ./my-app

2. CPU Limits

  • CPUQuota: Calculated as a percentage. If the server has 4 cores and you set it to 200%, the script can use the power of up to 2 cores.

3. Disk I/O Limits

To prevent backup scripts from clogging disk bandwidth, limit the write speed:

sudo systemd-run --scope -p "IOWriteBandwidthMax=/dev/sda 10M" ./heavy-write-script.sh

Real-time Resource Monitoring

How do you know how many resources the running commands are consuming? Don’t use top; use systemd-cgtop. It displays resources according to the cgroups structure very intuitively.

systemd-cgtop

You will see the transient units appear with specific CPU/RAM figures. If you want to stop a background task, just use the familiar stop command: sudo systemctl stop backup-job.

Field Experience: When Should You Use It?

Through my operations experience, I’ve found the following three scenarios to be the most ideal:

  1. Data Crawling: Python scripts are prone to memory leaks. Setting MemoryMax helps the script stop itself before it brings down the entire server.
  2. Compressing Old Logs: Using gzip on heavy log files often pushes the Load Average very high. Limiting CPUQuota=15% allows the compression to run quietly in the background without causing web lag.
  3. SSH Operations: When the network is unstable, using systemd-run --unit ensures the command runs safely even if the connection is lost.

Note: You need sudo privileges to interact with cgroups. If you want to run with regular user privileges, you’d need to configure complex cgroup v2 delegation, so using sudo is faster.

Conclusion

systemd-run is not just a command; it’s a modern system administration mindset. Instead of letting scripts ‘run wild,’ confining them to a fixed resource frame keeps your server stable. Try applying it to your daily scripts today to see the difference.

Share: