Systemd Timers vs. Cron: Choosing the Right Scheduler

Compare cron and systemd timers so you can choose the right Linux scheduler for simple jobs, services, logging, and dependencies.

Systemd Timers vs. Cron: Choosing the Right Scheduler

When your Linux server needs to run a backup, cleanup, health check, or report on a schedule, you usually choose between cron and systemd timers. Cron is still simple and portable. Systemd timers fit better when the job behaves like a managed service and needs logs, dependencies, or resource controls.

The right choice depends on the machine you run, the job's failure behavior, and how much operational visibility you need.

Understanding Cron Jobs

cron is a time-based job scheduler in Unix-like operating systems. It allows users to schedule commands or scripts to run periodically at fixed times, dates, or intervals. The cron daemon (crond) runs in the background and checks the crontab files for any scheduled jobs.

How Cron Works

Each user can have their own crontab file, managed using the crontab command. System-wide jobs are typically configured in /etc/crontab or files within /etc/cron.d/.

A crontab entry follows a specific format:

* * * * * command_to_execute
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€ Day of week (0 - 6) (Sunday=0 or 7)
โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Month (1 - 12)
โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Day of month (1 - 31)
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Hour (0 - 23)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Minute (0 - 59)

Example: To run a backup script every day at 2:00 AM:

0 2 * * * /usr/local/bin/backup.sh

Advantages of Cron

  • Ubiquitous: Available on virtually all Unix-like systems.
  • Simple Syntax: The crontab format is relatively easy to learn for basic scheduling.
  • User-Specific Jobs: Easy to set up jobs for individual users.

Disadvantages of Cron

  • Limited Flexibility: Primarily based on fixed time intervals. Handling complex dependencies or event-driven scheduling is difficult.
  • No Dependency Management: Cannot easily define that a job should only run after another job completes successfully.
  • No Resource Control: Offers little to no control over the resources (CPU, memory) consumed by scheduled jobs.
  • Logging and Monitoring: Often relies on mail output, syslog, or explicit redirection in the command.
  • Unit File Integration: Not directly integrated with systemd's service management capabilities.

Understanding Systemd Timers

systemd timers are a more advanced and flexible way to schedule tasks, leveraging the power of systemd's unit files. Instead of a separate daemon, systemd timers are managed as part of the systemd init system itself.

How Systemd Timers Work

systemd timers consist of two unit files:

  1. Service Unit (.service): Defines the task or command to be executed.
  2. Timer Unit (.timer): Defines when the corresponding service unit should be activated.

These files are typically placed in /etc/systemd/system/ or ~/.config/systemd/user/.

Example: Scheduling a cleanup script to run daily at 3:00 AM.

First, create the service file (cleanup.service):

# /etc/systemd/system/cleanup.service

[Unit]
Description=Daily cleanup task

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

Next, create the timer file (cleanup.timer):

# /etc/systemd/system/cleanup.timer

[Unit]
Description=Run cleanup task daily

[Timer]
# Run 25 minutes after boot, and then daily at 3 AM
OnBootSec=25min
OnCalendar=*-*-* 03:00:00
# Alternative: Run 24 hours after the last execution
# OnUnitActiveSec=24h

[Install]
WantedBy=timers.target

After creating these files, reload systemd, enable the timer for future boots, and start it now:

sudo systemctl daemon-reload
sudo systemctl enable cleanup.timer
sudo systemctl start cleanup.timer

You can check the status of the timer and when it will next trigger using:

sudo systemctl status cleanup.timer

Key systemd Timer Directives:

  • OnCalendar=: Specifies a calendar event time (similar to cron's syntax but more powerful).
    • *-*-* 03:00:00: Daily at 3 AM.
    • Mon..Fri *-*-* 09:00:00: Weekdays at 9 AM.
    • hourly: Every hour.
    • daily: Once a day.
    • weekly: Once a week.
    • monthly: Once a month.
    • yearly: Once a year.
  • OnBootSec=: Triggers a specified time after the system boots.
  • OnUnitActiveSec=: Triggers a specified time after the corresponding unit (service) was last activated.
  • OnUnitInactiveSec=: Triggers a specified time after the corresponding unit (service) became inactive.
  • AccuracySec=: How precise the timer needs to be. Lower values might consume more power.
  • Persistent=: For calendar timers, true tells systemd to catch up when a scheduled run was missed while the timer was inactive, such as when the machine was powered off.

Advantages of Systemd Timers

  • Integration with systemd: Seamlessly integrates with systemd's service management, logging (journalctl), resource control, and dependency management.
  • Flexibility: Supports various scheduling options beyond fixed intervals, including calendar events, relative times after boot, and relative times after previous activation.
  • Dependency Management: Can define dependencies on other systemd units (e.g., network availability).
  • Resource Control: Can leverage systemd's cgroups for resource limiting (CPU, memory).
  • Logging: Integrated with journald for comprehensive and centralized logging.
  • Error Handling: Can use service-unit behavior such as Restart=, OnFailure=, and dependency ordering where those patterns fit the job.
  • State Awareness: Can track when a job was supposed to run and execute it upon system startup if Persistent=true is set.

Disadvantages of Systemd Timers

  • Steeper Learning Curve: The systemd unit file syntax and concepts can be more complex than cron for beginners.
  • Systemd Dependency: Requires a system running systemd (most modern Linux distributions do).

Systemd Timers vs. Cron: Key Differences Summarized

Feature Cron Jobs Systemd Timers
Management crontab command, system files systemctl command, unit files
Scheduling Fixed minute, hour, day, month, weekday Calendar events, relative times, boot-based
Integration Standalone daemon Integrated with systemd
Logging Mail, script redirection journald
Dependencies None systemd unit dependencies
Resource Ctrl None systemd cgroups
Error Handling Basic Service-unit failure handling
State Tracking Limited Persistent= option
Complexity Simpler for basic tasks More powerful, steeper learning curve

When to Choose Which Scheduler

Choose Cron When:

  • You are on a very old or minimal system that does not use systemd.
  • You need to schedule a very simple, one-off task with a fixed, recurring schedule, and you prioritize simplicity over advanced features.
  • You need a quick schedule for a command that already handles its own logging and errors.

Choose Systemd Timers When:

  • You are on a modern Linux distribution that uses systemd.
  • You need more control over when a job runs (e.g., relative to boot, relative to last run, after network is up).
  • You require better logging, monitoring, and error handling.
  • You want to manage job execution with systemd's powerful service management features, including resource control and dependency management.
  • You are already managing other services with systemd and want a consistent approach to scheduling.
  • Your tasks have dependencies on other system services or events.

Practical Rule of Thumb

Use cron when the job is a short, obvious command and portability matters. Use a systemd timer when the job is part of a service, needs journalctl logs, should wait for the network, or benefits from resource limits and dependency ordering.

A nightly backup is a good example. On a small legacy server, 0 2 * * * /usr/local/bin/backup.sh may be enough. On a systemd-based production host, a backup.service plus backup.timer gives you clearer status, logs, boot catch-up with Persistent=true, and a cleaner path to add dependencies later.