Common cron expressions and how to check the next run
What the five fields mean, a set of expressions worth memorising, and the day-of-month versus day-of-week trap.
The five fields
A cron expression describes a schedule with five space-separated fields: minute, hour, day of month, month, and day of week.
Minute runs 0 to 59, hour 0 to 23, day 1 to 31, month 1 to 12, and day of week 0 to 6 with 0 meaning Sunday. Some implementations also accept 7 for Sunday.
Each field takes four kinds of notation: an asterisk for every value, a slash for intervals (*/5 meaning every fifth), a hyphen for ranges (1-5), and a comma for lists (1,15). Those four cover nearly every schedule that comes up in practice.
Expressions worth memorising
These forms appear over and over in real systems.
- */5 * * * * — every five minutes, typical for health checks and short sync jobs.
- 0 * * * * — on the hour, for hourly aggregation.
- 0 3 * * * — daily at 03:00, the classic slot for backups and cleanup.
- 0 9 * * 1-5 — weekdays at 09:00, for business-day notifications.
- 0 0 1 * * — midnight on the first of the month, for monthly settlement or reports.
- 30 2 * * 0 — Sundays at 02:30, suited to weekly maintenance.
The day-of-month and day-of-week trap
This is the most misunderstood behaviour in cron. When both the day-of-month and day-of-week fields are specified, standard cron combines them with OR, not AND.
So 0 0 1 * 1 runs on the first of every month and also on every Monday. If you expected it to run only when the first falls on a Monday, the result is completely different.
To require both conditions, schedule on one of them and test the other inside the script: run every Monday, and exit immediately unless the date is the first.
When the job does not run as expected
When the expression is right but the job misbehaves, the cause is usually the environment rather than cron itself.
- Server time zone: cron follows the server clock, so a UTC server interprets the hour field as UTC.
- Environment variables: the shell cron uses differs from a login shell, and a short PATH that cannot find your command is a classic failure. Use absolute paths.
- Overlapping runs: a slow previous execution can still be running when the next one starts. Guard with a lock file or flock.
- Standard output: cron tries to mail any output. Without redirection to a log file, diagnosing anything is painful.
- Field count: Spring and Quartz add a seconds field and expect six. A five-field expression shifts meaning entirely.