Skip to content

Systemd Timers

Comprehensive Guide to Scheduled Tasks with systemd

Section titled “Comprehensive Guide to Scheduled Tasks with systemd”

systemd timers are the modern replacement for cron in Linux systems:

  • Modern Systems: New Linux systems use systemd timers instead of cron
  • Reliability: Timers can persist missed jobs, handle system sleep
  • Logging: Better integration with journald for log management
  • On-Call: You’ll manage scheduled jobs and investigate missed executions
  • Certification: RHCSA and RHCE cover systemd timers

Most production servers now use systemd timers for scheduled tasks.


systemd Timers
+------------------------------------------------------------------+
| |
| What are timers? |
| +----------------------------------------------------------+ |
| | • Units that trigger service activation at specific times | |
| | • Modern replacement for cron | |
| | • More precise and flexible | |
| | • Survive reboots with Persistent=true | |
| +----------------------------------------------------------+ |
| |
| Components: |
| +----------------------------------------------------------+ |
| | Timer unit (.timer) - defines schedule | |
| | Service unit (.service) - defines what to run | |
| +----------------------------------------------------------+ |
| |
| Advantages over cron: |
| +----------------------------------------------------------+ |
| | • Dependencies on other services | |
| | • Can be triggered by events | |
| | • Better logging via journal | |
| | • Can run missed jobs on boot | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

/etc/systemd/system/mytimer.timer
[Unit]
Description=My Scheduled Timer
Requires=myservice.service
[Timer]
# Time-based triggers
OnCalendar=daily # Every day at midnight
OnCalendar=Mon *-*-* 02:00:00 # Every Monday at 2 AM
OnCalendar=*:0/15 # Every 15 minutes
OnCalendar=*-*-01 00:00:00 # First day of month
# Time from events
OnBootSec=5min # 5 minutes after boot
OnActiveSec=1h # 1 hour after activation
OnUnitActiveSec=1h # 1 hour after service last ran
# Options
Persistent=true # Run missed jobs on boot
RandomizedDelaySec=1h # Random delay to prevent storms
WakeSystem=true # Wake system from suspend
AccuracySec=1us # Accuracy (default: 1min)
Unit=myservice.service # Default service to trigger
[Install]
WantedBy=timers.target
Calendar Format
+------------------------------------------------------------------+
| |
| Examples: |
| +----------------------------------------------------------+ |
| | daily | Every day at midnight | |
| | hourly | Every hour | |
| | weekly | Every Monday at midnight | |
| | monthly | First day of month | |
| | *-*-01 00:00:00| 1st of month at midnight | |
| | Mon *-*-* 02:00 | Every Monday at 2 AM | |
| | *-*-* *:0/15 | Every 15 minutes | |
| | *-*-* 12:00:00 | Every day at noon | |
| | 2024-*-* 00:00 | Daily after Jan 1, 2024 | |
| | *:0/5:0 | Every 5 seconds | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

/etc/systemd/system/myservice.service
[Unit]
Description=My Scheduled Service
[Service]
Type=oneshot # Run once and exit
ExecStart=/usr/local/bin/myscript.sh
User=root
StandardOutput=journal
StandardError=journal
# Or for long-running services:
# Type=simple
# RemainAfterExit=no

Terminal window
# List all timers
systemctl list-timers
systemctl list-timers --all
# Start/stop timer
sudo systemctl start mytimer.timer
sudo systemctl stop mytimer.timer
# Enable/disable timer
sudo systemctl enable mytimer.timer
sudo systemctl disable mytimer.timer
# Check timer status
systemctl status mytimer.timer
# View next run times
systemctl list-timers | grep mytimer
# Manual trigger (test)
sudo systemctl start myservice.service
# View related logs
journalctl -u myservice.service
journalctl -u mytimer.timer -f

/etc/systemd/system/daily-backup.timer
[Unit]
Description=Daily Backup Timer
Requires=daily-backup.service
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=30m
[Install]
WantedBy=timers.target
/etc/systemd/system/weekly-cleanup.timer
[Unit]
Description=Weekly Cleanup
Requires=weekly-cleanup.service
[Timer]
OnCalendar=Sun 3:00
Persistent=true
[Install]
WantedBy=timers.target
/etc/systemd/system/health-check.timer
[Unit]
Description=Hourly Health Check
Requires=health-check.service
[Timer]
OnCalendar=*:0/60 # Every hour
WakeSystem=true
[Install]
WantedBy=timers.target

  1. What are systemd timers?

    • Units for scheduling tasks, modern replacement for cron
  2. What does Persistent=true do?

    • Runs missed jobs after reboot
  3. What’s the difference between cron and systemd timers?

    • Timers have better logging, dependencies, and persist across reboots
  4. What is OnCalendar?

    • Calendar-based scheduling syntax

Quick Reference
+------------------------------------------------------------------+
| |
| Commands: |
| +----------------------------------------------------------+ |
| | systemctl list-timers | List timers | |
| | systemctl start timer | Start timer | |
| | systemctl enable timer | Enable at boot | |
| +----------------------------------------------------------+ |
| |
| Key Options: |
| +----------------------------------------------------------+ |
| | OnCalendar | Calendar schedule | |
| | Persistent=true | Run missed jobs | |
| | RandomizedDelaySec | Random delay | |
| +----------------------------------------------------------+ |
| |
+------------------------------------------------------------------+

WRONG:

Terminal window
# Only start, not enable
sudo systemctl start backup.timer
# Timer won't start after reboot

CORRECT:

Terminal window
# Enable to start at boot
sudo systemctl enable --now backup.timer

Why: Without enable, timer doesn’t survive reboot.


WRONG:

OnCalendar=daily
# Too vague - runs at midnight every day

CORRECT:

OnCalendar=*-*-02 04:30:00
# Runs at 4:30 AM on 2nd of each month

Why: Specific schedules prevent confusion and conflicts.


  1. Q: What’s the advantage of systemd timers over cron?

    • A: Timers persist across system sleep/hibernate, better logging via journald, dependencies can control when jobs run, can delay randomly to prevent thundering herd.
  2. Q: How do you debug a timer that isn’t firing?

    • A: Check systemctl status timer, check journalctl -u service, verify timer is enabled, check next activation time with systemctl list-timers.

End of Chapter 82: systemd Timers