Systemd
Stop using cron! Systemd Timers Explained
Table of Contents

Stepping into the vast world of Linux, I was armed with a mission: schedule my Python backup script to run regularly. The criteria seemed straightforward — execute every 30 minutes, refrain from overlapping runs, and have an option for manual testing. Simple, right?
I was in for a surprise.
In this post I’ll be diving into the world of task scheduling on Linux, covering cron and systemd timers along the way.
1.0 Intro
Coming from a Windows background, I thought setting up scheduled tasks on Linux would be straightforward. Windows has been handling these tasks with ease for a long time. However, I quickly realized that Linux had its own set of challenges.
That’s where systemd comes in.
systemd manages services on many Linux distributions.
Info
Currently, systemd is the default for many popular Linux distributions, including:
- Red Hat Enterprise Linux (RHEL)
- CentOS
- Ubuntu
- Debian
- SUSE
- Arch
With that background, let’s dive into systemd timers and explore why they might be a better choice than the traditional cron.
2.0 Systemd Unit Files
Consider a typical crontab entry:
*/30 * * * * /usr/bin/python3 /path/to/your/script.py
This cron job runs at minute 0 and 30 of each hour. The systemd example below uses a boot-relative interval instead. Two separate unit files are needed:
- Service File: Defines what you want to run.
- Timer File: Specifies when and how the service should execute.
Here’s how these files are structured:
Service File (/etc/systemd/system/myscript.service):
[Unit]
Description=Execute my python script
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /path/to/your/script.py
Timer File (/etc/systemd/system/myscript.timer):
[Unit]
Description=Run myscript.service every 30 minutes
[Timer]
OnBootSec=5min
OnUnitActiveSec=30min
[Install]
WantedBy=timers.target
After saving the files, load and start the timer:
sudo systemctl daemon-reload
sudo systemctl enable --now myscript.timer
systemctl status myscript.timer
Replace the placeholder script path first. Record systemd --version and the distribution release when testing, and inspect the journal after both a scheduled run and a manual start.
3.0 Benefits
3.1 Non-overlapping
An already-active service is left running when its timer elapses; a second instance is not queued. This does not prevent someone running the script separately.
3.2 On-demand execution
Systemd allows you to manually start tasks:
$ systemctl start myscript.service
This feature enables immediate testing or intervention, removing the guesswork of “Will it run correctly next time?”.
You can also run a cron command manually. Starting the systemd service uses its configured execution environment and logging.
3.3 Unified Logging
systemd provides central logging through journald.
With the service’s default output settings, stdout and stderr go to the journal. Cron output can also be mailed or redirected to a log; the script does not need its own logging implementation.
To probe the logs for our myscript.service, execute:
$ journalctl -u myscript.service
This command retrieves the service’s activity logs, streamlining troubleshooting and performance assessment.
3.4 Granular Timing
OnCalendar accepts seconds, but the default AccuracySec=1min permits coalescing within a one-minute window. Tighten that window explicitly:
[Timer]
OnCalendar=*-*-* 12:00:15
AccuracySec=1s
This is not an exact-second guarantee: timer slack, system load and service startup can delay execution. Times use the local timezone unless specified otherwise.
For spreading work, use RandomizedDelaySec; AccuracySec primarily coalesces wake-ups:
[Timer]
OnCalendar=hourly
RandomizedDelaySec=15m
A boot-relative timer needs no persistence setting:
[Timer]
OnBootSec=15min
Persistent=true only affects OnCalendar timers. A calendar alternative to the boot-relative example is:
[Timer]
OnCalendar=*-*-* *:00,30:00
Persistent=true
Reactivation catches up with one invocation if at least one run was missed, not one per missed interval; any randomised delay still applies.
These semantics were checked against the official systemd.timer manual on 28 September 2026. The examples have not been rerun on a Linux host for this revision; check your installed man systemd.timer for version-specific behaviour.
3.5 Error Handling
Imagine a task fails. Rather than just shrugging it off, systemd can kick off another service to handle the mishap.
Dreaming of getting notified on Slack when something’s amiss? There’s a Slack notifier for that! Old school and prefer a trusty email? Dive into this mailto script.
In contrast, cron offers a simpler, more limited approach.
3.6 Birds Eye View
Gaining a unified perspective of all scheduled tasks in systemd is a breeze:
$ systemctl list-timers --all
This lists timers loaded by the system manager, including inactive ones. Use systemctl --user list-timers --all for the current user’s manager; it is not an inventory of every user’s timers. See the systemctl manual.
Contrast this with cron. Each user’s tasks lie within individual crontabs. To inspect, you’d hop between users:
$ crontab -u <username> -l
And don’t forget the system wide tasks in /etc/crontab and /etc/cron.d. In this realm, systemd offers clarity where cron asks for a scavenger hunt.
3.7 Dependencies
Systemd timers execute tasks intellligently.
Ever been in a situation where you need to confirm a database service is alive and kicking before running that crucial backup?
Systemd’s got your back:
[Unit]
Description=Backup service
Requires=database.service
After=database.service
What about ensuring NFS file shares are mounted beforehand?
[Unit]
Description=MySQL backup task
Requires=mybackupshare.mount
After=mybackupshare.mount
4.0 Drawbacks
4.1 Complexity
Cron’s beauty lies in its simplicity.
Simply drop a line in a crontab you’ve got a task set to run periodically:
* * * * * /path/to/script.sh
On the flip side, systemd, while undeniably robust, can feel like a double-edged sword. Setting up a timer isn’t a brief affair. It mandates two separate unit files: the service and the timer.
Essentially, you’re looking at double the configuration, doubling the chances for an oversight.
5.0 Summary
Cron and systemd timers serve distinct roles in the Linux world. While cron remains the go-to for straightforward scheduling, systemd timers cater to modern system management with precise timing, advanced error handling, and dependency management capabilities.
Choosing between the two boils down to the task at hand. Having both tools in your toolkit ensures you’re well-prepared for any scheduling challenge.
Thanks for reading, and happy scheduling!