Systemd Timer: Modern Alternative to Cron
Use systemd timers to schedule periodic tasks. More reliable than cron: integrated logs, dependencies, error handling and automatic retries.
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
EOFTimer 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
EOFActivation
systemctl daemon-reload
systemctl enable --now backup-daily.timer
# Verify
systemctl status backup-daily.timerOnCalendar 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:00Verify 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=30minPersistent=true
[Timer]
OnCalendar=daily
Persistent=truePersistent=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.timerPractical 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.targetAutomatic 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.targetCron 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.
Download Files from Google Drive to VPS
How to download large files from Google Drive directly to a Linux VPS via terminal, bypassing the 100MB limit and confirmation redirects.
Rsync File Sync & Backup
Use rsync to sync files between servers, create incremental backups, and automate transfers over SSH