Systemd Timers vs Cron: A Modern Alternative for Scheduled Tasks

Throughout this series, cron has quietly handled scheduling for backup scripts, cleanup jobs, and update checks.

cron

Throughout this series, cron has quietly handled scheduling for backup scripts, cleanup jobs, and update checks. Systemd timers offer a more modern alternative built directly into the systemd ecosystem (), providing better logging, dependency handling, and integration with the rest of your system’s services.

Why Consider Systemd Timers Over Cron

  • Integrated logging via journalctl – timer-triggered service runs appear directly in the systemd journal, searchable and filterable the same way as any other service log, rather than needing separate cron log configuration
  • Dependency awareness – a systemd timer’s associated service can specify dependencies (network availability, a specific mount point) that cron has no native concept of
  • Missed run handling – systemd timers can be configured to run a missed job immediately upon boot if the system was off during its scheduled time, something cron doesn’t handle natively
  • Consistent management interface – enabling, disabling, and checking timer status uses the same systemctl commands already familiar from managing any other systemd service

Understanding the Two-File Structure

Unlike cron’s single-line entries, systemd timers require two separate unit files working together: a .service file defining what to actually run, and a .timer file defining when to run it.

Creating the Service File

sudo nano /etc/systemd/system/backup-cleanup.service

ini

[Unit]
Description=Clean up old backup files

[Service]
Type=oneshot
ExecStart=/home/user/scripts/cleanup.sh

The Type=oneshot setting indicates this service runs once and exits, rather than running continuously like a typical background service.

Creating the Timer File

sudo nano /etc/systemd/system/backup-cleanup.timer

ini

[Unit]
Description=Run backup cleanup daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

The Persistent=true option specifically enables the “run missed jobs on boot” behavior mentioned earlier — if the system was powered off during the scheduled time, the job runs shortly after the next boot instead of being skipped entirely.

Understanding OnCalendar Syntax

Systemd’s calendar syntax is more readable than cron’s numeric fields for common schedules:

OnCalendar=daily
OnCalendar=weekly
OnCalendar=*-*-* 03:00:00
OnCalendar=Mon,Wed,Fri 09:00

Test any calendar expression before relying on it:

systemd-analyze calendar "Mon,Wed,Fri 09:00"

This shows the next several scheduled trigger times, letting you confirm the syntax produces the schedule you actually intended.

Enabling and Starting the Timer

sudo systemctl daemon-reload
sudo systemctl enable --now backup-cleanup.timer

Note that you enable and start the .timer unit, not the .service unit directly — the timer itself triggers the associated service at the scheduled times.

Checking Timer Status

systemctl list-timers

This shows every active timer on the system, including when each last ran and when it’s next scheduled to trigger.

Reviewing Execution Logs

journalctl -u backup-cleanup.service

This shows the output and any errors from every past run of the associated service, integrated directly into the same journal used for every other systemd-managed service on the system.

When Cron Still Makes Sense

For very simple, quick scheduled tasks, cron’s single-line simplicity remains genuinely convenient — creating two separate unit files for a trivial one-line command feels like unnecessary overhead. Systemd timers earn their added complexity specifically for jobs that benefit from dependency handling, missed-run recovery, or want their execution history truly integrated into the same logging and monitoring approach as the rest of your systemd-managed services.

Migrating Existing Cron Jobs

For any cron jobs from earlier guides in this series (log rotation checks, cleanup scripts, update automation) that would benefit from systemd’s additional capabilities, converting them follows the same basic pattern shown above — a service file defining what to run, a timer file defining when, enabled together via systemctl.

Final Thoughts

Systemd timers offer a really more integrated, more observable alternative to cron for scheduled tasks, particularly valuable for jobs where missed-run recovery or dependency awareness actually matters. For simple, low-stakes scheduling, cron’s continued simplicity remains perfectly reasonable — but for anything where you’ve found yourself wanting better logging or wondering whether a cron job actually ran successfully, systemd timers close that gap directly.

Related Posts

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *