↗ systemd-run in Practice - Scheduling, Sandboxing, cgroups, and Automation

When you need to run a one-off task in the background or schedule a maintenance script for later, the usual tools that come to mind are nohup, screen, at, or cron.
But if your servers already use systemd, you also have access to a much more powerful tool: systemd-run.
It creates transient units — temporary services and timers that do not require permanent .service or .timer files.
With transient units, you can get proper process supervision, journald logging, cgroup resource limits, sandboxing, scheduling, and status tracking without adding permanent systemd configuration.
Let’s look at a few practical use cases.
1. One-off scheduling without cron or at
Suppose you need to restart a service at 4 AM, when traffic is low.
Creating a permanent timer or adding a temporary cron entry for a one-time operation is unnecessary.
You can schedule it directly:
sudo systemd-run --on-calendar="04:00:00" /bin/systemctl restart zbld
You can also use an exact date and time:
sudo systemd-run \
--on-calendar="2026-08-27 04:00:00" /bin/systemctl restart zbld
For relative scheduling, such as running something two hours from now:
sudo systemd-run --on-active="2h" /usr/local/bin/cleanup-script.sh
Why use this instead of cron?
A few useful advantages:
- Centralized logging — stdout and stderr are available through
journalctl. - Process supervision — systemd tracks the process and its exit status.
- Visibility — scheduled transient timers can be inspected with:
systemctl list-timers
- No permanent configuration files — useful for one-off maintenance tasks.
One important detail: transient units created with systemd-run do not survive a reboot.
If you need a timer that survives reboots and catches up on missed executions, use a persistent .timer unit with:
Persistent=true
That behavior belongs to persistent systemd timers, not transient timers created with systemd-run.
