Home/Engineer/OS / Systems/systemd Timers: Replacing cr…
OS / SystemsIntermediateUbuntuDebianCentOSsystemdtimercron

systemd Timers: Replacing cron Jobs with Scheduled Units, Failure Alerts, and Logs

How to schedule recurring jobs with systemd timer units, configure failure notifications, logs, and delayed execution, plus the trade-offs versus cron.

Contents
  1. systemd timer vs cron
  2. Basic structure — .service + .timer pair
  3. Example: daily backup
  4. OnCalendar expressions
  5. Run a set time after boot
  6. Failure notifications
  7. Logs and manual runs

systemd timer vs cron

Aspectcronsystemd timer
LogsMixed into syslogIntegrated with journalctl
Failure detectionDifficultAutomatic (OnFailure=)
DependenciesNoneAfter=, Requires=
Missed-run catch-upNonePersistent=true
Execution environmentLimitedSame 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 schedule

Example: 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=journal
INI
# /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.target
Bash
# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable --now mybackup.timer

# Check status
systemctl status mybackup.timer
systemctl list-timers

OnCalendar 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 midnight
Bash
# 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 hour

Failure 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.timer
#systemd#timer#cron#linux
Editorial 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.