Linux
cron or systemd timers
Applies to Linux This applies to any Linux distribution running systemd; the cron notes hold on any Unix-like system with a cron daemon.
cron is universal and familiar. systemd timers are more verbose to write and better in most of the ways that matter operationally.
What timers give you
Logging by default. A timer’s output goes to the journal, attributed to the unit. cron emails output to a local mailbox nobody reads, and if mail is not configured it is discarded entirely. Most cron failures are silent for this reason.
Missed runs. Persistent=true runs a job that was missed while the machine was off. cron simply skips it.
No overlap. systemd will not start a unit already running. A cron job that runs longer than its interval accumulates copies of itself, which is a classic way to bring down a server slowly.
Dependencies. A timer can require the network to be up, or order itself after another service. cron has no concept of this.
Randomised delay. RandomizedDelaySec stops fifty machines hitting the same server at exactly midnight.
A minimal pair
# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Timer]
OnCalendar=02:30
RandomizedDelaySec=300
Persistent=true
[Install]
WantedBy=timers.target
systemctl enable --now backup.timer
systemctl list-timers --all
journalctl -u backup.service --since today
When cron is still right
A user-level job, something trivial, or a system where you cannot rely on systemd. There is no virtue in converting a working cron job that nobody has ever had trouble with.
If you keep cron
Redirect output somewhere you will see it. A cron job whose output goes nowhere has no failure reporting at all — it will fail silently for months.
30 2 * * * /usr/local/bin/backup.sh 2>&1 | logger -t backup
Related reading