Skip to main content

Cron vs systemd

Cron is the classic scheduler. systemd timers are the modern default on systemd-based distros. This page explains the real differences you will care about when jobs fail at 03:00.

Quick Summary
  • Cron is portable and simple.
  • systemd timers provide better logging, missed-run replay, and dependencies.
  • If systemd exists, timers are usually the safer default for production jobs.

Feature comparison

CapabilityCronsystemd timerOperational impact
Portabilitystrongmediumcron works almost everywhere
Missed runsweakstrongtimers can replay missed jobs
Logs by defaultweakstrongjournald gives a timeline
Dependenciesweakstrongcan wait for mounts/network
Resource limitsweakstrongcap CPU/memory/I/O
Environment controlweakstrongexplicit PATH, user, env
Overlap preventionmanualeasierstill use locks when needed

Migration example: cron -> timer

The cron entry

cron-backup-entry.txt
15 2 * * * /usr/local/bin/wp-backup-run >>/var/log/wp-backup.log 2>&1

The systemd units

/etc/systemd/system/wp-backup.service
[Unit]
Description=WordPress backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/wp-backup-run
/etc/systemd/system/wp-backup.timer
[Unit]
Description=Run WordPress backup daily

[Timer]
OnCalendar=*-*-* 02:15:00
Persistent=true
RandomizedDelaySec=5m

[Install]
WantedBy=timers.target

Enable and inspect:

enable-and-check-systemd-timer.sh
sudo systemctl daemon-reload
sudo systemctl enable --now wp-backup.timer
systemctl list-timers --all | rg -n 'wp-backup'

View logs:

view-timer-job-logs.sh
journalctl -u wp-backup.service --since '24 hours ago' --no-pager

When cron is still the right choice

  • You are in a non-systemd environment.
  • You need maximum portability.
  • The job is simple and you already have logging and locking.

Common timer gotchas

  • Timers run a service unit; the service defines user, working directory, and environment.
  • If you need a specific user, set User= in the service.
  • If your job depends on mounts or network, express that in [Unit] dependencies.

Quick commands you will actually use:

systemd-timer-debug-commands.sh
systemctl list-timers --all | sed -n '1,80p'
systemctl --no-pager --full status wp-backup.timer || true
systemctl --no-pager --full status wp-backup.service || true

# test run now
sudo systemctl start wp-backup.service

Next steps

  • Cron basics: opt/docker-data/apps/docusaurus/site/docs/server/linux-server/11-automation-task-execution/cron.mdx
  • System clock and timezone: opt/docker-data/apps/docusaurus/site/docs/server/linux-server/11-automation-task-execution/cron-depends-on-datetimectl.mdx