LinuxComparisonsystemd6 min read

Cron vs at vs systemd Timers: When to Use Each

Linux has three main tools for scheduled job execution. Understanding the strengths of each helps you pick the right one for your use case — and avoid common pitfalls.

TL;DR — Quick Decision Guide

  • cronUse for recurring schedules — backups every night, reports every Monday, cleanup every hour.
  • atUse for one-time future tasks — send a reminder in 3 hours, run a script at 2am tomorrow.
  • systemdUse when you need full logging, dependency handling, or want missed jobs to catch up — modern servers with systemd.

cron— the classic recurring scheduler

cron has been the standard Unix job scheduler since the 1970s. It reads a crontab file and runs each command when its 5-field time expression matches the current time.

# Edit your crontab

crontab -e

# Run backup every night at 2am
0 2 * * * /usr/local/bin/backup.sh

# Run report every Monday morning
0 9 * * 1 /usr/local/bin/weekly-report.sh

# Clear tmp files every hour
0 * * * * find /tmp -mtime +1 -delete

Strengths

  • • Simple, universal — every Linux/macOS system has it
  • • No setup required for basic recurring jobs
  • • Per-user crontabs for multi-user systems

Limitations

  • • Missed jobs are silently skipped (no catchup)
  • • Minimal PATH — common source of failures
  • • No dependency management

at— one-time future execution

The at command schedules a command to run once at a specified time. It accepts natural language time specifications and captures your current environment automatically.

# Schedule a job for tomorrow at 9am
echo "/path/to/script.sh" | at 9am tomorrow

# Schedule in 2 hours
echo "/path/to/script.sh" | at now + 2 hours

# Schedule at a specific date/time
echo "/path/to/script.sh" | at 14:30 Dec 31

# View the queue
atq

# Remove a job (job number from atq)
atrm 3

Strengths

  • • Natural language time input
  • • Captures current shell environment automatically
  • • Perfect for one-off administrative tasks

Limitations

  • • One-time only — no recurring schedules
  • • Not installed by default on all distros
  • • Limited logging and monitoring

systemd timers— modern service-integrated scheduling

systemd timers are unit files that trigger services on a schedule. They integrate with systemd's dependency graph, logging (journald), and service management — making them more powerful but more complex to set up.

# /etc/systemd/system/backup.service

[Unit]
Description=Nightly Backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

# /etc/systemd/system/backup.timer

[Unit]
Description=Run backup nightly

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true   # Run missed jobs on next startup

[Install]
WantedBy=timers.target

# Enable and check status

sudo systemctl enable --now backup.timer
systemctl list-timers
journalctl -u backup.service

Strengths

  • • Full journald logging — always
  • Persistent=true catches up missed jobs
  • • systemd dependency graph
  • systemctl status shows last run time

Limitations

  • • More setup — requires two unit files
  • • systemd-only (no macOS, no old Linux)
  • • Steeper learning curve

Full Feature Comparison

Featurecronatsystemd timer
Use caseRecurring schedulesOne-time future executionRecurring or one-time, service-integrated
Schedule syntax5-field cron expressionNatural language time ("tomorrow 9am")Calendar events or monotonic timers
Persistence across rebootsYesYes (queue survives reboot)Yes, when enabled
Missed job handlingSkipped silentlyRuns when system is availableCan run missed jobs with Persistent=true
Loggingsyslog/journald (varies)Limitedjournald (full log, always)
Dependency managementNoneNoneFull systemd dependency graph
EnvironmentMinimal PATH, no shell envCaptures current env at schedule timeExplicit unit config
Email on outputYes (via MAILTO)Yes (by default)No (log to journal)
Multi-user supportPer-user crontabsPer-user queueSystem or user units
AvailabilityDefault on most Linux/macOSNeeds `at` packageMost modern Linux distros

Write cron expressions the easy way

Use our visual builder to create cron expressions by selecting schedule options — no syntax memorization needed.