Systemd Timer: Modern Alternative to Cron
systemd timers are the modern alternative to cron. Each timer is linked to a .service unit and executed by systemd: with complete logs on journald, error handling and the ability to define dependencies between services.
Basic structure
A systemd timer requires two files:
- .service: defines what to execute
- .timer: defines when to execute it
Example: daily backup script
Service file
cat > /etc/systemd/system/backup-daily.service << 'EOF'
[Unit]
Description=Daily server backup
After=network.target
[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/backup.sh
StandardOutput=journal
StandardError=journal
EOF
Timer file
cat > /etc/systemd/system/backup-daily.timer << 'EOF'
[Unit]
Description=Run backup every day at 2:00
Requires=backup-daily.service
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
EOF
Activation
systemctl daemon-reload
systemctl enable --now backup-daily.timer
# Verify
systemctl status backup-daily.timer
OnCalendar syntax
The OnCalendar syntax is more readable than cron:
# Every day at 3:30
OnCalendar=*-*-* 03:30:00
# Every Monday at 8:00
OnCalendar=Mon *-*-* 08:00:00
# First of every month at midnight
OnCalendar=*-*-01 00:00:00
# Every hour
OnCalendar=hourly
# Every day
OnCalendar=daily
# Every week (Monday at 00:00)
OnCalendar=weekly
# Every 15 minutes
OnCalendar=*:0/15
# Every 6 hours
OnCalendar=0/6:00:00
# Monday-Friday at 9:00
OnCalendar=Mon..Fri *-*-* 09:00:00
Verify syntax
# Check when the timer will trigger
systemd-analyze calendar "*-*-* 02:00:00"
systemd-analyze calendar "Mon *-*-* 08:00:00"
Relative timers (OnBootSec, OnUnitActiveSec)
[Timer]
# Run 5 minutes after boot
OnBootSec=5min
# Then every 30 minutes
OnUnitActiveSec=30min
Persistent=true
[Timer]
OnCalendar=daily
Persistent=true
Persistent=true means: if the timer didn't trigger at the scheduled time (server was off), run it immediately at next boot. Equivalent to cron's MAILTO option to not miss executions.
Timer management
# List all active timers
systemctl list-timers
# List all timers (including inactive)
systemctl list-timers --all
# Status of specific timer
systemctl status backup-daily.timer
# Run the service immediately (without waiting for timer)
systemctl start backup-daily.service
# Service logs
journalctl -u backup-daily.service -n 50
# Real-time logs
journalctl -u backup-daily.service -f
# Disable the timer
systemctl disable --now backup-daily.timer
Practical examples
Weekly log cleanup
# /etc/systemd/system/clean-logs.service
[Unit]
Description=Clean old logs
[Service]
Type=oneshot
ExecStart=/usr/bin/find /var/log -name "*.log" -mtime +30 -delete
ExecStart=/usr/bin/journalctl --vacuum-time=30d
# /etc/systemd/system/clean-logs.timer
[Unit]
Description=Weekly log cleanup
[Timer]
OnCalendar=Sun *-*-* 04:00:00
Persistent=true
[Install]
WantedBy=timers.target
Automatic updates
# /etc/systemd/system/auto-update.service
[Unit]
Description=Automatic system updates
[Service]
Type=oneshot
ExecStart=/usr/bin/apt update
ExecStart=/usr/bin/apt upgrade -y
ExecStart=/usr/bin/apt autoremove -y
# /etc/systemd/system/auto-update.timer
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
Cron vs systemd timer
| Cron | Systemd Timer | |
|---|---|---|
| Logs | ❌ Only via syslog | ✅ integrated journald |
| Retry on error | ❌ No | ✅ With Restart=on-failure |
| Dependencies | ❌ No | ✅ After=, Requires= |
| Persistent | ❌ Skips if offline | ✅ Catches up at boot |
| Simplicity | ✅ One line | ⚠️ Two files |
| Familiar | ✅ Everyone knows it | ⚠️ Learning curve |
For simple tasks without special requirements, cron is still valid. For critical tasks where logs and reliability matter, use systemd timers.
Gerelateerde artikelen
Server Reboot
How to properly restart your VPS or VDS, both via SSH and from the control panel
Resource Monitoring
How to check CPU, RAM, disk and network on your server in real time
Disk Management
How to check disk space, find large files and free up disk space
