Stage 3 · Build
Boot & Init Systems
systemd Timers
OnCalendar, monotonic timers, persistent runs, and replacing cron with systemctl list-timers.
Timer Overview
systemd timers replace cron for scheduling recurring tasks. Each timer unit has a corresponding service unit that runs when the timer fires. Timers provide better logging, dependency management, and missed-run handling.
# List all active timers
systemctl list-timers --all
# NEXT LEFT LAST PASSED UNIT
# Mon 2024-01-15 06:00:00 UTC 5h left Sun 2024-01-14 06:00:00 UTC 19h ago fstrim.timer
# Mon 2024-01-15 00:00:00 UTC 23h left Sun 2024-01-14 00:00:00 UTC 24h ago logrotate.timer
# Mon 2024-01-15 03:00:00 UTC 2h left Sun 2024-01-14 03:00:00 UTC 21h ago tmp.timer
# Show timer details
systemctl status fstrim.timer
# ● fstrim.timer - Discard unused filesystem blocks
# Active: active (waiting) since ...
# Triggers: Mon 2024-01-15 06:00:00 UTCsystemctl list-timers shows all timers with their next and last trigger times. This is the systemd equivalent of crontab -l.
OnCalendar Syntax
# OnCalendar syntax: DayOfWeek Year-Month-Day Hour:Minute:Second
# Every day at 3:00 AM
OnCalendar=*-*-* 03:00:00
# Every Monday at 2:00 AM
OnCalendar=Mon *-*-* 02:00:00
# Every hour
OnCalendar=*-*-* *:00:00
# Every 15 minutes
OnCalendar=*-*-* *:00/15:00
# Every Sunday at midnight
OnCalendar=Sun *-*-* 00:00:00
# 1st of every month at 4:00 AM
OnCalendar=*-*-01 04:00:00
# Every 5 minutes (cron-like)
OnCalendar=*:0/5
# Test your calendar expression
systemd-analyze calendar "Mon *-*-* 02:00:00"
# R=2024-01-15T02:00:00
systemd-analyze calendar "daily" --iterations=3
# R=2024-01-15T00:00:00
# R=2024-01-16T00:00:00
# R=2024-01-17T00:00:00OnCalendar uses a flexible time specification. Use systemd-analyze calendar to test expressions before creating timers.
Monotonic Timers
# OnBootSec — Trigger N seconds after boot
OnBootSec=5min
# OnUnitActiveSec — Trigger N seconds after unit was last active
OnUnitActiveSec=1h
# OnUnitInactiveSec — Trigger N seconds after unit became inactive
OnUnitInactiveSec=30min
# OnStartupSec — Trigger N seconds after systemd started
OnStartupSec=10min
# Example: run backup 30 minutes after boot, then every 6 hours
# /etc/systemd/system/backup.timer
[Timer]
OnBootSec=30min
OnUnitActiveSec=6h
Persistent=true
[Install]
WantedBy=timers.targetMonotonic timers are relative to system events (boot, unit activation). They are more predictable than calendar-based timers for recurring tasks.
Persistent Timers
# Persistent=true ensures the timer runs missed runs
# If the system was off when a timer was supposed to fire,
# it will run immediately on next boot
# /etc/systemd/system/logrotate.timer
[Unit]
Description=Run logrotate daily
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
# Check persistent timer state
cat /var/lib/systemd/timers/logrotate.timer
# LAST_TRIGGER_USEC=1705238400000000
# NEXT_ELAPSED_USEC=1705324800000000
# Without Persistent=true, missed runs are lostPersistent timers record their last trigger time and run missed jobs on boot. Essential for log rotation, backups, and cleanup tasks.
Timer Operations
# Enable a timer
sudo systemctl enable mytimer.timer
sudo systemctl start mytimer.timer
# Check timer status
systemctl status mytimer.timer
systemctl show mytimer.timer | grep -E "OnCalendar|NextElapse|LastTrigger"
# Manually trigger a timer
sudo systemctl start mytimer.service
# Reset timer state
sudo systemctl daemon-reload
# Disable timer
sudo systemctl stop mytimer.timer
sudo systemctl disable mytimer.timer
# List timer unit files
systemctl list-unit-files --type=timerTimer management is similar to service management. enable/start to activate, stop/disable to deactivate.
Migrating from cron
# Cron: 0 3 * * * /usr/bin/backup.sh
# systemd equivalent:
# /etc/systemd/system/backup.service
[Unit]
Description=Daily Backup
[Service]
Type=oneshot
ExecStart=/usr/bin/backup.sh
User=root
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
# Enable
sudo systemctl enable --now backup.timer
# Compare with cron
# ✅ Better logging (journalctl -u backup.service)
# ✅ Dependency management
# ✅ Missed run handling (Persistent=true)
# ✅ Resource control (CPUQuota, MemoryMax)
# ✅ Security hardening (CapabilityBoundingSet)systemd timers offer significant advantages over cron: logging, dependency management, resource control, and security hardening.
Before creating a timer, test your OnCalendar expression with systemd-analyze calendar. This prevents scheduling mistakes.
systemd timers provide better logging, dependency management, and security than cron. Use them for all new scheduled tasks.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.