A systemd timer is two units that share a name: a .service that does the work, and a .timer that triggers it on a schedule. You enable the timer. This replaces */5 * * * * in cron, with proper logging and systemctl list-timers.
1. The service (the work)
Save as /etc/systemd/system/backup-sync.service:
[Unit]
Description=Sync backups to remote
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-sync.sh
A timer-driven service is Type=oneshot and has no [Install] section — the timer starts it, so it must not be enabled on its own.
2. The timer (the schedule)
Save as /etc/systemd/system/backup-sync.timer (same base name):
[Unit]
Description=Run backup-sync every 5 minutes
[Timer]
OnCalendar=*:0/5
Persistent=true
[Install]
WantedBy=timers.target
OnCalendar=*:0/5means “every hour, at minutes 0, 5, 10, … 55” — i.e. every 5 minutes.Persistent=trueruns the job once on boot if its scheduled time was missed while the machine was off (cron’s@rebootcatch-up done right).- Because the timer’s base name matches the service, no
Unit=line is needed.
Enable the timer
sudo systemctl daemon-reload
sudo systemctl enable --now backup-sync.timer
Verify and inspect
systemctl list-timers backup-sync.timer # next & last run
systemctl status backup-sync.service # last result
journalctl -u backup-sync.service -f # output of each run
sudo systemctl start backup-sync.service # run it once, right now
Validate OnCalendar before trusting it: systemd-analyze calendar '*:0/5' prints the next elapses. Gotchas: enable the .timer, never the .service. If runs can overlap or stampede across many hosts, add RandomizedDelaySec= (see the randomized-timer recipe).