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.

Loading the interactive guide…

The fields

#FieldAllowedNames
1Minute0–59–
2Hour0–23–
3Day of month1–31–
4Month1–12JAN–DEC
5Day of week0–6 (7)SUN–SAT

Special characters

SymbolMeaningExampleReads as
*Every value* * * * *every minute
,List0 9,17 * * *09:00 and 17:00
-Inclusive range0 9 * * 1-509:00 Monday to Friday
/Step*/10 * * * *every 10 minutes
a-b/nStep within a range0 8-18/2 * * *08:00, 10:00 … 18:00
?No specific value (Quartz/AWS)0 0 12 ? * MONnoon on Mondays
LLast (Quartz/AWS)0 0 L * ?last day of the month
WNearest weekday (Quartz/AWS)0 0 15W * ?weekday nearest the 15th
#Nth weekday (Quartz/AWS)0 0 ? * MON#1first 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

MacroEquivalentMeaning
@yearly / @annually0 0 1 1 *Midnight, 1 January
@monthly0 0 1 * *Midnight on the 1st
@weekly0 0 * * 0Midnight on Sunday
@daily / @midnight0 0 * * *Every day at 00:00
@hourly0 * * * *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.

Questions

What is the cron format?
Five space-separated fields: minute (0–59), hour (0–23), day of month (1–31), month (1–12 or JAN–DEC) and day of week (0–6 or SUN–SAT, Sunday = 0). In a crontab file the command follows the five fields on the same line.
What do *, /, - and , mean in cron?
* matches every value, a comma separates a list (1,15), a hyphen makes an inclusive range (9-17), and a slash adds a step to a range or to * (*/10 = every 10th value starting at the lowest).
Is Sunday 0 or 7?
In standard cron Sunday is 0, and Vixie cron, cronie and most modern implementations also accept 7. In Quartz and AWS EventBridge the numbering is different: 1 is Sunday and 7 is Saturday. Using names like SUN avoids the confusion.
What are L, W and # in cron?
They are Quartz and AWS extensions. L means last (last day of month, or last Friday with 6L / FRIL), W means nearest weekday (15W), and # picks the nth weekday of a month (MON#2 = second Monday). Standard crontab does not support them.
What time zone does cron use?
The time zone of the system running the cron daemon. Some crons (cronie) accept CRON_TZ=Europe/Berlin at the top of a crontab. Kubernetes has spec.timeZone; GitHub Actions and Vercel always use UTC.