Cron syntax and format
A cron expression is five fields that each answer one question: which minute, which hour, which day of the month, which month, which day of the week. The job runs whenever all of them agree.
Walk through the five fields
Step through each field and swap its value. The rule underneath strikes every value the field matches, and the sentence updates as you go.
The fields
| # | Field | Allowed | Names |
|---|---|---|---|
| 1 | Minute | 0–59 | – |
| 2 | Hour | 0–23 | – |
| 3 | Day of month | 1–31 | – |
| 4 | Month | 1–12 | JAN–DEC |
| 5 | Day of week | 0–6 (7) | SUN–SAT |
Special characters
| Symbol | Meaning | Example | Reads as |
|---|---|---|---|
* | Every value | * * * * * | every minute |
, | List | 0 9,17 * * * | 09:00 and 17:00 |
- | Inclusive range | 0 9 * * 1-5 | 09:00 Monday to Friday |
/ | Step | */10 * * * * | every 10 minutes |
a-b/n | Step within a range | 0 8-18/2 * * * | 08:00, 10:00 … 18:00 |
? | No specific value (Quartz/AWS) | 0 0 12 ? * MON | noon on Mondays |
L | Last (Quartz/AWS) | 0 0 L * ? | last day of the month |
W | Nearest weekday (Quartz/AWS) | 0 0 15W * ? | weekday nearest the 15th |
# | Nth weekday (Quartz/AWS) | 0 0 ? * MON#1 | first Monday |
A step counts from the start of its range, not from “now”. */7 in the minute field runs at :00, :07 … :56 and then again at :00, so the gap at the top of the hour is 4 minutes. Cron has no memory of the last run.
Macros
| Macro | Equivalent | Meaning |
|---|---|---|
@yearly / @annually | 0 0 1 1 * | Midnight, 1 January |
@monthly | 0 0 1 * * | Midnight on the 1st |
@weekly | 0 0 * * 0 | Midnight on Sunday |
@daily / @midnight | 0 0 * * * | Every day at 00:00 |
@hourly | 0 * * * * | Top of every hour |
@reboot | – | Once when cron starts |
Macros work in Vixie cron and cronie (most Linux distributions) and in Kubernetes. GitHub Actions, Vercel and AWS need the full expression.
The day-of-month / day-of-week rule
This surprises almost everyone once. If either day field is *, the other one decides. If both are restricted, POSIX cron runs the job when either matches. 0 12 1 * 1 runs at noon on the 1st of every month and on every Monday. Quartz and AWS avoid the ambiguity by requiring ? in one of the two fields.
Time zones
Cron uses the clock of the machine it runs on. Check it with timedatectl or date. Some implementations accept a CRON_TZ= line at the top of the crontab. During daylight-saving changes, a job scheduled inside the skipped hour may not run, and one inside the repeated hour may run twice or once depending on the implementation: schedule critical jobs outside 01:00–03:00 local time, or run the server in UTC.