Cron Syntax Mastered
Stop guessing your cron expressions. Master every field, edge case, and modern alternative.
Cron is the most-used scheduler in computing and the most-misunderstood. Five fields, decades of legacy quirks.
The Five Fields
* command
| |
| | | | day of week (0-6, Sun=0)
| | | month (1-12)
| | day of month (1-31)
| hour (0-23)
minute (0-59)
Some implementations add a sixth seconds field at the front (Quartz, some K8s CronJobs).
Common Patterns
0 Every hour on the hour
/15 * Every 15 minutes
0 0 * Every day at midnight
0 0 0 Every Sunday midnight
0 9 1-5 Weekdays at 9am
0 0 1 First of every month
0 0 1 1 * January 1st only
@reboot Once at boot (some implementations)
@daily Once per day at midnight
The OR Trap
Day-of-month and day-of-week are OR'd, not AND'd. 0 0 1 * 0 runs on the 1st OF EVERY MONTH AND every Sunday. To AND them, use a guard inside the script.
Step Values
/5 * every 5 minutes (0, 5, 10, ...)
0 /6 every 6 hours (0, 6, 12, 18)
0 0 /2 * every 2 days
Ranges and Lists
0 9-17 1-5 hourly during work hours, weekdays
0 0 1,15 on the 1st and 15th
Modern Alternatives
- systemd timers — better logging, dependency support
- Kubernetes CronJob — same syntax, container scheduling
- GitHub Actions schedule — cron-syntax for workflows
- Cloudflare Cron Triggers — for Workers
- node-cron, croner — embedded scheduling in apps
All speak cron syntax to keep migration friction low.
Avoiding Pitfalls
- Cron runs in the daemon's timezone, often UTC. Verify with
timedatectl. - DST transitions cause skipped or duplicate runs. Use UTC for jobs that must fire exactly once.
- Long-running jobs can overlap. Use a lockfile or job queue.
- Capture stdout/stderr; default behavior loses output to mail.
Test patterns interactively with the [Cron Expression Tester](https://sdk.is/cron-tester).