systemd Timers: A Modern Alternative to Cron
systemd Timers Replace Cron with Better Observability and Control
systemd timers are a functional replacement for traditional cron daemons, offering superior logging, predictable environment variables, and flexible scheduling based on both calendar events and relative time spans. Unlike cron, which often suffers from ambiguous $PATH settings and "black hole" output (where stdout and stderr are lost or sent to local mail), systemd timers integrate directly with journalctl for centralized logging and allow for precise control over the execution environment.
Core Architecture: The Timer and Service Split
A systemd timer consists of two separate unit files: a .timer file that defines the schedule and a .service file that defines the action to be performed. By default, a timer will look for a service unit with the same name (stem) as the timer file.
Implementing a Basic Timer
To set up a scheduled task, you must create both a service and a timer unit in /etc/systemd/system/:
- The Service Unit (
.service): Defines what to run.- Note:
ExecStart=does not run as a shell command by default. To use pipes or shell logic, you must call an interpreter like/usr/bin/bash -c. - Conditional Execution: The
ExecCondition=option provides a native way to determine if a service should run, offering cleaner logs than wrapping logic inside a bash script.
- Note:
- The Timer Unit (
.timer): Defines when to run.- The
OnCalendar=setting is used for wall-clock schedules (e.g.,10:00for daily at 10 AM). - The
[Install]section withWantedBy=timers.targetensures the timer starts at boot.
- The
Management Commands
- Start a timer:
systemctl start <name>.timer - Check next execution:
systemctl status <name>.timer - List all active timers:
systemctl list-timersprovides a bird's-eye view of all scheduled tasks, their last execution time, and when they are next due.
Advanced Scheduling Capabilities
systemd timers support two primary types of scheduling: calendar-based events and relative time spans.
Calendar Events
Users can use shorthand (like daily) or fully qualified forms (e.g., *-*-* 00:00:00). The systemd-analyze calendar tool allows users to validate these expressions and see the exact next time a timer will fire.
Relative Time Spans
Unlike cron, systemd can trigger events relative to other system states:
OnBootSec=: Runs a task a specific amount of time after the machine boots.OnUnitActiveSec=: Runs a task a specific amount of time after the last time the unit was activated, creating a repeating cycle that is not tied to a specific wall-clock minute.
Solving Distributed Systems Problems
systemd provides built-in mechanisms to prevent "thundering herd" problems—where many systems trigger the same task simultaneously—and to handle system downtime.
Randomizing Execution
RandomizedOffsetSec=: Offsets the timer by a randomly selected amount of time, distributing the load across a window.FixedRandomDelay=: Ensures the random delay is deterministic and remains stable across restarts.
Handling Missed Events
Persistent=: When set to true, systemd stores the last trigger time on disk. If the system was powered off when a timer should have fired, the service is triggered immediately upon the next activation.WakeSystem=: If supported by the hardware, this can wake a suspended system from sleep to execute a scheduled task.
Community Perspectives and Trade-offs
While many developers advocate for the move to systemd timers, the transition involves several trade-offs:
Advantages
- Integration: Direct integration with
journalctleliminates the need to manually pipe output tologgeror check local mail for failures. - Debugging: Services can be started manually via
systemctl start <name>.servicefor immediate testing without waiting for the timer. - Resilience: Users report that timers are more resilient to system startup times compared to
cronie.
Criticisms
- Complexity: Some users find the requirement of two separate files (timer and service) to be "clunky" or "silly" compared to a single line in a crontab.
- Discoverability: Critics argue that
crontab -lis a faster way to see all scheduled tasks than searching through various systemd unit directories. - Learning Curve: The syntax of unit files is often viewed as less intuitive for beginners than the traditional cron format.
"I've slowly moved all of my ansible-deployed cron jobs to timers... The integration with journalctl, especially in a newer OS like Debian 13 where syslog is gone, is really nice." — @kayson