Cron vs systemd Timers: When I Reach for Each
Advertisement
Every time this comes up, someone argues that systemd timers should replace cron entirely. They aren't wrong about the features: timers have better logging, dependency management, and can survive a server reboot if they missed a scheduled run. Yet, I still write cron jobs regularly. The choice isn't about features; it's about who has to read the code next year and how much ceremony the job actually deserves.
Where cron wins: small, simple, well-known
A cron job is one line. Anyone who has touched Linux in the last twenty years can read a crontab and understand it instantly:
# /etc/cron.d/cleanup-tmp
0 3 * * * root find /tmp -type f -atime +7 -delete
For jobs like this, the systemd equivalent is two files (a .service and a .timer) plus an enable step. That's a lot of overhead for something so basic. The issue isn't the typing—it's discoverability. During an incident, the first thing most Linux admins check is crontab -l or /etc/cron.d/. A systemd timer that nobody knows to look for effectively doesn't exist.
My rule: if the job is a single command, doesn't need failure handling, and a missed run wouldn't matter, use cron.
Where systemd timers win: anything you have to trust
The second a scheduled job actually matters—backups, certificate renewals, anything where a silent failure triggers a 2 AM pager—systemd timers earn their keep.
# /etc/systemd/system/backup.service
[Unit]
Description=Nightly database backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup nightly
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
systemctl enable --now backup.timer
journalctl -u backup.service
systemd gives you three things cron doesn't:
journalctl -u backup.serviceshows the full output and exit status of every run. No need to redirect stdout/stderr to a log file and hope logrotate doesn't break.Persistent=trueguarantees the job runs when the server boots up if it missed its scheduled 2 AM slot.systemctl status backup.timerexplicitly tells you when it ran last and when it runs next.
The deciding question
When I set up a new scheduled task, I don't care which tool is "more modern." I ask: if this job fails silently, how long before someone notices, and does it matter?
If it doesn't really matter (e.g., a tmp cleanup or a cache warm-up), cron's simplicity is a feature. If it's the only thing standing between the business and data loss, the extra two files and native logging of a systemd timer are non-negotiable.
Most servers I manage have both: a few cron one-liners for housekeeping, and a small list of systemd timers for critical jobs. This isn't a compromise—it's matching the tool to the task.
Advertisement