Linux Cron vs systemd Timers for Scheduled Jobs
Quick answer
Quick answer: cron is simple and available everywhere, but it has a minimal environment, no built-in logging, and no catch-up for missed runs. Systemd timers...
Quick answer: cron is simple and available everywhere, but it has a minimal environment, no built-in logging, and no catch-up for missed runs. Systemd timers integrate with the journal, can run missed jobs after downtime, and reuse service features like resource limits and dependencies. Use cron for quick, simple schedules and timers for jobs that need reliability and observability.
How Do Cron and systemd Timers Differ?
Cron reads schedule lines from a crontab and runs the command at matching times. It has existed for decades, works on virtually every Unix-like system, and the syntax is compact. Its simplicity is its appeal, and also its limit: it only knows how to start a command at a time.
A systemd timer is a pair of units. The timer unit defines when to run, and a separate service unit defines what to run. Because the job is an ordinary service, it benefits from everything systemd offers: logging through the journal, dependencies and ordering, resource controls, sandboxing options, and a clear status you can query. The cost is more configuration, since you write two files instead of one line.
Another difference is the schedule language. Cron uses five fields, while timers use a calendar expression or monotonic triggers, such as a delay after boot or after the last run. Calendar expressions are readable and can be validated with a built-in command before you deploy them.
Which Operational Problems Do Timers Solve?
Several familiar cron headaches have direct answers in timers:
- Missed runs: if the machine is off at the scheduled time, cron skips the job. A timer with the persistent option runs it at the next opportunity.
- Logging: cron output is mailed or discarded unless you redirect it. Timer services log to the journal automatically, searchable by unit.
- Overlapping runs: cron will start a second copy if the first is still running. A timer will not start a service that is already active, which prevents most overlap.
- Environment: cron runs with a minimal environment, which causes works-in-terminal failures. Services have explicit, documented environment settings.
- Load spikes: a randomized delay spreads many machines across a time window so they do not all hit a shared service together.
# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup
[Service]
Type=oneshot
User=backup
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup nightly
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
After enabling the timer unit, you can list upcoming runs and see the last result with systemctl, and read output with the journal. Check the systemd documentation for the options supported by your version.
When Is Cron Still the Right Choice?
Cron remains practical for simple, low-stakes jobs, for systems without systemd such as some minimal containers or older distributions, and for users who want a personal schedule without root access or unit files. It is also familiar to nearly everyone, which reduces onboarding friction on small teams.
If you stay with cron, make jobs robust. Use absolute paths, set the environment variables you need inside the script, redirect output to a log file or the system logger, and guard against overlap with a lock, using a file locking utility so a slow run cannot stack on top of the next one. Add monitoring that alerts when a job fails or does not run, because cron will not tell you.
For anything business-critical, such as backups, billing exports, or data pipelines, timers or a dedicated scheduler give you the visibility and recovery behavior you will want at 3 a.m. For distributed or containerized environments, orchestrator-level schedulers are often a better fit than per-host cron.
Frequently Asked Questions
Can systemd timers replace cron entirely?
On systemd-based systems, yes for most uses. Cron may still be convenient for quick user-level jobs or systems without systemd.
How do I run a missed job after the machine was off?
Set the persistent option on the timer. Systemd records the last trigger time and runs the job once at boot or resume if it was missed.
Why does my cron job work manually but fail in cron?
Cron uses a minimal environment and a short PATH. Use absolute paths and set required variables in the script or crontab.
How do I prevent two runs from overlapping?
With cron, wrap the command in a lock. With timers, the service unit will not start again while it is still active, though long jobs deserve explicit checks.
Summary
Cron is minimal and universal, while systemd timers add logging, persistence, overlap protection, and service features. Choose timers for reliability-sensitive jobs on systemd hosts, and make cron jobs explicit about paths, output, and locking. Confirm timer options in the systemd documentation for your version.