Plainnotes

Two surprises after moving from cron to systemd timers

2026-08-03 · 4 min readSystems

Moving a backup script from crontab to a systemd timer looked like a one-to-one translation. Two things went wrong.

Catch-up is not what you expect

Persistent=true fires once, immediately at boot, rather than shifting the schedule. The script was set for 03:30; the box rebooted at four, ran the backup straight away, and landed in the middle of the boot-time disk scan. Adding After=network-online.target and a short sleep fixed it.

Editing a unit without reloading keeps the old timer

I changed OnCalendar from daily to weekly. systemctl list-timers showed the new time, but the old schedule kept firing. You need:

systemctl daemon-reload
systemctl restart backup.timer

OnCalendar follows the system timezone, and containers are usually UTC — 03:30 there is 11:30 in Beijing. systemd-analyze calendar '*-*-* 03:30:00' prints the next absolute trigger. And RandomizedDelaySec is good for spreading out jobs that start together, but destroys "on the dot"; leave it off for backups.