Linux Performance

cron vs systemd timers

Practical Linux guide: cron vs systemd timers without the usual guesswork.

10 min read Beginner Updated 9 Jun 2026

Step-by-step guide

Work through each section in order. Stop when your issue is resolved — you do not need every step for every situation.

What you will achieve

Pick between cron and systemd timers for scheduled jobs — logging, randomised delays, and dependency awareness on modern Debian/Ubuntu.

1) Classic cron

crontab -e
# system-wide: /etc/cron.d/ or /etc/cron.daily/
# Example: daily backup at 02:15
15 2 * * * /usr/local/bin/backup.sh

2) systemd timer

# /etc/systemd/system/backup.service
[Unit]
Description=Backup job

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup

[Timer]
OnCalendar=*-*-* 02:15:00
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl enable --now backup.timer
systemctl list-timers

3) When timers win

  • Jobs need After=network-online.target.
  • You want journald logs via journalctl -u backup.service.
  • Missed runs should catch up (Persistent=true).

Verify

systemctl status backup.timer
grep CRON /var/log/syslog | tail

5) Randomised delay (systemd)

[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=900

Prevents thousand hosts hitting API at identical second.

6) anacron for laptops

/etc/cron.daily on Debian uses anacron — jobs run when machine was off at scheduled time. systemd Persistent=true solves same problem on systemd-only paths.

7) Environment variables

# cron struggles with minimal PATH
PATH=/usr/local/bin:/usr/bin:/bin
0 3 * * * /usr/local/bin/backup.sh

systemd service units set Environment= explicitly — clearer than cron hacks.

Migration tip

Convert critical cron jobs to timers one at a time. Run both in parallel briefly and compare journald output vs cron mail.

8) daylight saving gotchas

Cron local time jumps on DST — systemd calendar expressions handle transitions more predictably for wall-clock schedules.

Prerequisites

Script tested manually as correct user. Timezone set (timedatectl). Mail or logging for job output. Root for system timers in /etc/systemd/system/.

cron MAILTO

MAILTO=admin@example.com
0 4 * * * /usr/local/bin/backup.sh

Requires working mail — otherwise cron silently drops output unless redirected to log file.

systemd timer OnBootSec

OnBootSec=15min

Run job 15 minutes after boot — handy for laptop that misses OnCalendar while asleep.

Overlap protection

systemd OnUnitActiveSec= prevents pile-up if job runs longer than interval — cron fires regardless and stacks duplicate backups. Use flock -n /var/lock/backup.lock in cron scripts for same protection on legacy cron paths.

anacron on servers always on

anacron redundant when systemd Persistent timers exist — pick one maintenance path. Mixed cron.daily and systemd timer duplicating same backup wastes I/O and confuses on-call about which log to read.

Timezone explicit

systemd OnCalendar uses local timezone unless UTC specified — document whether backup runs 02:00 Europe/London or UTC to avoid daylight saving surprises for global teams.

Related guides

cron linux systemd timers vs