Cron vs. Systemd Timers: Which Should You Use?

Cron is the undisputed king of background scheduling, but systemd timers offer powerful modern features. Let's compare the two.

For nearly 50 years, cron has been the default way to run scheduled tasks on Unix-like systems. But in recent years, the widespread adoption of systemd has brought a powerful new contender to the ring: Systemd Timers.

If you're provisioning a new Linux server today, which one should you choose for your background jobs?

The Case for Cron

Cron's biggest advantage is its sheer ubiquity and simplicity.

The syntax (* * * * *) is universally recognized, and editing a crontab is as easy as running crontab -e. Its simplicity makes it incredibly portable across different distributions, macOS, and even embedded systems.

When to use Cron:

  • You have simple, standalone scripts.
  • You need the job to be easily portable via a single text file.
  • You are not heavily reliant on complex service dependencies.

The Case for Systemd Timers

Systemd timers treat scheduled tasks as first-class citizens alongside your main application services. They consist of two files: a .service file that defines what to run, and a .timer file that defines when to run it.

Advantages of Systemd:

  1. Dependency Management: You can tell a timer to only run if the PostgreSQL service is currently active and healthy.
  2. Nanosecond Precision: Cron is limited to minute-level resolution. Systemd can run exact microsecond intervals.
  3. Advanced Logging: Output from systemd timers goes directly into the journalctl system, automatically capturing stdout/stderr with timestamps natively.
  4. Randomized Delays: You can use RandomizedDelaySec to prevent the "thundering herd" problem (where hundreds of servers try to hit an API at exactly midnight).

Monitoring Both Paradigms

Regardless of which tool you use to schedule your tasks, you still face the "Silent Failure" problem. Neither cron nor systemd natively pushes an alert to your Slack channel if the job throws an exception.

The solution in both environments is identical: instrumentation.

At the end of your script (or within your systemd .service definition via ExecStopPost), you must fire a heartbeat to a service like CronRabbit.

# Example Systemd Service with CronRabbit Heartbeat
[Unit]
Description=My Daily Backup Job

[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
# Ping CronRabbit only on success
ExecStopPost=/bin/sh -c 'if [ "$EXIT_STATUS" = 0 ]; then curl -m 10 https://ping.cronrabbit.com/xyz; fi'

Ultimately, if your infrastructure is already heavily invested in systemd, moving your cron jobs to systemd timers offers much tighter integration. But for quick, simple tasks, standard cron remains hard to beat.