Replace a cron job with a systemd timer
A systemd timer runs a service on a schedule like cron, but logs every run to the journal, can catch up missed runs and is easy to test by hand.
Not checked by a trusted editor yet Last edited Outdated?
Cron is fine for simple jobs, but its output disappears unless mail is set up, a job missed while the server was off simply does not run, and testing “what will happen at 02:30” is awkward. A systemd timer is two small unit files: a .service that says what to run and a .timer that says when.
This example replaces the crontab line 30 2 * * * /usr/local/bin/backup.sh.
1. The service: what to run
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
sudo nano /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=root
Type=oneshot means the job runs to completion and exits, which is what a scheduled script does. There is no [Install] section: the timer starts this service, not the boot process.
2. The timer: when to run
Give the timer the same base name. If you do not set Unit=, a timer starts the service with the same name.
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
sudo nano /etc/systemd/system/backup.timer
[Unit]
Description=Run the nightly backup at 02:30
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=10min
[Install]
WantedBy=timers.target
OnCalendar=: a calendar expression.*-*-* 02:30:00is every day at 02:30.Persistent=true: remember the last run on disk; if the server was off at 02:30, run the job once as soon as the timer starts again.RandomizedDelaySec=: add a random delay of up to 10 minutes, so many servers do not all hit the backup target at the same second.
3. Check the schedule before enabling
systemd-analyze calendar parses an expression and shows when it will next fire:
systemd-analyze calendar '*-*-* 02:30:00'
systemd-analyze calendar --iterations=5 'Mon..Fri *-*-* 09:00'
Useful expressions:
dailyis*-*-* 00:00:00;weeklyis Monday at 00:00.Mon..Fri *-*-* 09:00: weekdays at 09:00.*:0/15: every 15 minutes (minute 0, 15, 30, 45).*-*-01 04:00:00: the first day of each month at 04:00.
For “every N minutes after the last run” instead of wall-clock times, use monotonic timers such as OnBootSec=5min together with OnUnitActiveSec=1h.
4. Enable the timer and test the job
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer # NEXT and LAST run times
sudo systemctl start backup.service # run the job right now, as a test
journalctl -u backup.service -n 30 # its output and exit status
Note that you enable the timer, not the service. Starting the service by hand is the easiest way to test the exact environment the timer will use.
5. Remove the old cron entry
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
sudo crontab -e # delete the backup line
Cron to timer cheat sheet
@rebootbecomesOnBootSec=1min.0 * * * *becomesOnCalendar=hourly.*/10 * * * *becomesOnCalendar=*:0/10.0 3 * * 0becomesOnCalendar=Sun *-*-* 03:00:00.- Cron’s MAILTO output becomes
journalctl -u name.service.
If the job fails, systemctl status backup.service shows failed and it appears in systemctl --failed, which makes it easy to pick up with monitoring.
Official documentation
Did this work for you?
No votes yet. Be the first.
If it did not work, the report form below tells the editors what went wrong.
See also
- 0164 systemd services: systemctl and journalctl basics systemd starts and supervises services on most Linux servers. systemctl starts, stops and enables them; journalctl shows their logs. Beginner · Explains an idea · Linux Article Services & systemd 15 Oct 2026
- 0165 Write a systemd service unit for your own app Turn any long-running program into a proper service: create a unit file, run it as an unprivileged user, restart it on failure… Intermediate · Step by step · Linux Article Services & systemd 15 Oct 2026
- 0167 Fix: Job for nginx.service failed because the control process exited with error code systemctl prints this when a service's start command exits with an error. The real reason is in journalctl; for nginx it is… Intermediate · Fixes an error · Linux Article Networking & firewalls · Services & systemd 15 Oct 2026
- 0168 Server health check script: disk, memory and failed units A dependency-free bash script that checks disk and inode usage, available memory, load, failed systemd units and pending reboots, and exits non-zero… Intermediate · Cheat sheet · Linux Script Disks, LVM & filesystems · Services & systemd 15 Oct 2026
- 0255 Build a monitoring stack with Prometheus, node_exporter and Grafana on one Linux server Install Prometheus and node_exporter as systemd services, scrape and query host metrics with PromQL, then add Grafana with a dashboard and an… Intermediate · Guided project · Linux Article Prometheus & Grafana · Services & systemd 15 Oct 2026
- 0265 Turn a one-liner into a robust bash script: strict mode, options, logging, traps, locking and a schedule Grow a find-and-gzip one-liner step by step into a dependable bash script with strict mode, getopts, usage text, logging, error traps, dry-run,… Intermediate · Guided project · Linux, macOS Article Services & systemd · Shell scripting 15 Oct 2026
Repos in the wild
- systemd: the Linux system and service manager systemd/systemd The source of systemd, the init system and service manager on most Linux distributions, together with journald, networkd, resolved, timers and the systemctl tool. GitHub
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- Commitpedia +3,130 chars