systemd timer vs cron
| Aspect | cron | systemd timer |
|---|---|---|
| Logs | Mixed into syslog | Integrated with journalctl |
| Failure detection | Difficult | Automatic (OnFailure=) |
| Dependencies | None | After=, Requires= |
| Missed-run catch-up | None | Persistent=true |
| Execution environment | Limited | Same as the service unit |
Basic structure — .service + .timer pair
Bash
# Two files form a pair
/etc/systemd/system/mybackup.service # The job to run
/etc/systemd/system/mybackup.timer # The scheduleExample: daily backup
INI
# /etc/systemd/system/mybackup.service
[Unit]
Description=Daily database backup
After=network.target postgresql.service
[Service]
Type=oneshot
User=backup
ExecStart=/usr/local/bin/backup.sh
StandardOutput=journal
StandardError=journalINI
# /etc/systemd/system/mybackup.timer
[Unit]
Description=Run mybackup daily at 3am
[Timer]
OnCalendar=*-*-* 03:00:00 # Every day at 03:00
Persistent=true # Catch up immediately on missed runs
RandomizedDelaySec=300 # Random delay of up to 5 minutes (spread load)
Unit=mybackup.service # Optional (auto-linked by matching name)
[Install]
WantedBy=timers.targetBash
# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable --now mybackup.timer
# Check status
systemctl status mybackup.timer
systemctl list-timersOnCalendar expressions
CODE
*-*-* 00:00:00 # Every day at midnight
*-*-* 03:00:00 # Every day at 03:00
Mon *-*-* 09:00:00 # Every Monday at 09:00
*-*-1 00:00:00 # The 1st of every month at midnight
*-*-* 0/6:00:00 # Every 6 hours
hourly # Top of every hour (= *-*-* *:00:00)
daily # Every day at midnight (= *-*-* 00:00:00)
weekly # Every Monday at midnight
monthly # The 1st of every month at midnightBash
# Validate expressions
systemd-analyze calendar "*-*-* 03:00:00"
systemd-analyze calendar "Mon *-*-* 09:00:00"Run a set time after boot
INI
[Timer]
OnBootSec=5min # Run once 5 minutes after boot
OnUnitActiveSec=1h # Then repeat every hourFailure notifications
INI
# Add to mybackup.service
[Unit]
OnFailure=notify-failure@%n.service
# /etc/systemd/system/notify-failure@.service
[Unit]
Description=Failure notification for %i
[Service]
Type=oneshot
ExecStart=/usr/local/bin/notify-slack.sh "Timer %i failed"Logs and manual runs
Bash
# Full timer list (including next run time)
systemctl list-timers --all
# Service logs
journalctl -u mybackup.service --since today
journalctl -u mybackup.service -n 50
# Run immediately by hand (independent of the timer)
sudo systemctl start mybackup.service
# Stop only the timer (keep the service)
sudo systemctl stop mybackup.timer
sudo systemctl disable mybackup.timerEditorial note
AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us
Topic-related official docs (auto-linked · not per-claim sources)Linux man pages ↗
Questions & answers
Ask a question about this guide. We'll review and reply.