Systemd Timers for Periodic Scheduling in Debian
This article examines how the systemd init system provides robust, flexible alternatives to legacy cron daemons for periodic scheduling in Debian. It covers the dual-unit architecture of systemd timers, the distinct timing mechanisms available—including realtime calendar events and monotonic triggers—and the native features that make systemd-based automation more reliable for system administration.
The Systemd Timer Architecture
In Debian, systemd replaces standalone schedulers like
cron and anacron using timer units (files
ending in .timer). A systemd timer does not execute
commands directly; instead, it binds to and activates a matching service
unit (files ending in .service).
When a timer triggers, systemd starts the corresponding service unit,
which executes the defined task within systemd’s managed execution
environment. This provides access to advanced cgroup resource limits,
structured logging through journald, and strict dependency
resolution.
Realtime Timers (Calendar Events)
The primary alternative to traditional cron expressions in systemd is
the realtime timer, configured using the
OnCalendar= directive. Realtime timers trigger based on
wall-clock time and calendar dates.
Unlike cron’s five-field format, systemd calendar events use human-readable syntax that supports granular specifications from years down to seconds:
OnCalendar=*-*-* 04:00:00(daily at 4:00 AM)OnCalendar=Mon,Fri *-*-* 18:30:00(Mondays and Fridays at 6:30 PM)OnCalendar=hourlyordailyorweekly(convenient predefined shortcuts)
To match or exceed the functionality of anacron, systemd
timers support the Persistent=true directive. If the
machine is powered off or suspended when a scheduled run is due, systemd
immediately executes the service upon the next boot.
Monotonic Timers (Relative Events)
Monotonic timers schedule jobs relative to varying system states rather than the wall clock. These timers do not drift when the system clock changes (e.g., due to daylight saving adjustments or NTP updates) and provide scheduling paradigms that traditional cron cannot replicate:
OnBootSec=: Triggers a specific duration after the kernel has booted.OnStartupSec=: Triggers relative to when the systemd service manager itself initialized.OnUnitActiveSec=: Schedules a task relative to the moment the associated service was last activated.OnUnitInactiveSec=: Schedules a task relative to when the associated service finished its last execution, preventing task overlaps if a job runs longer than expected.
Multiple timing constraints can be combined in a single
.timer file, allowing jobs to run at boot and subsequently
repeat at regular intervals:
[Unit]
Description=Run maintenance script periodically
[Timer]
OnBootSec=15min
OnUnitActiveSec=1d
Persistent=true
[Install]
WantedBy=timers.targetTransient Timers with systemd-run
For ad-hoc tasks or command-line scripting where creating persistent
unit files on the filesystem is unnecessary, Debian users can generate
transient timers via the systemd-run
utility.
Transient timers create temporary timer and service units dynamically in memory:
- Relative execution:
systemd-run --on-active="2h" /usr/local/bin/backup.sh - Calendar execution:
systemd-run --on-calendar="daily" /usr/local/bin/cleanup.sh
Managing and Auditing Timers
Systemd includes native tooling to inspect, track, and monitor scheduled jobs without parsing disparate crontab files or user tables.
- View active timers: Run
systemctl list-timersto display all active timers, their next scheduled run time, the time elapsed since their last execution, and their associated service units. - View execution logs: Run
journalctl -u service-name.serviceto review dedicated stdout, stderr, and failure codes for the scheduled job.