Cron expression explainer
The tool works both ways: enter a schedule in crontab format to have it explained, or describe the schedule in words to get the expression.
Five fields: minute, hour, day of the month, month and day of the week. A sixth field for seconds may come first.
Examples
Means
Every 15th minute from 5 through 59, past hour 9–17, on Monday–Friday
Field by field
| Field | Expression | Values |
|---|---|---|
| Minute | 5-59/15 | 5, 20, 35, 50 |
| Hour | 9-17 | 9, 10, 11, 12, 13, 14, 15, 16, 17 |
| Day of the month | * | all |
| Month | * | all |
| Day of the week | MON-FRI | Monday, Tuesday, Wednesday, Thursday, Friday |
Next runs
…
Summer time is handled as in Vixie cron and cronie: a fixed time runs once even if the hour is skipped or repeated, while jobs with * in the minute or hour follow the new clock.
How it works
A cron expression has five fields separated by spaces: minute (0–59), hour (0–23), day of the month (1–31), month (1–12) and day of the week (0–7, where both 0 and 7 are Sunday). Every minute, cron checks whether the clock matches all the fields and, if it does, starts the job.
In each field * means every value, 1-5 a range, 1,15 a list and */15 every fifteenth value. Steps can also be combined with ranges: 5-59/15 gives minutes 5, 20, 35 and 50. Months and days of the week can be written as English abbreviations, JAN–DEC and SUN–SAT.
When both the day of the month and the day of the week are restricted, it is enough for one of them to match. 0 0 13 * 5 therefore runs on the 13th of every month and on every Friday, not only on Friday the 13th. The rule comes from Vixie cron and applies on most Linux systems. If either field starts with *, even with a step such as */2, both must match.
The macros @hourly, @daily, @weekly, @monthly and @yearly (or @annually) are shorthands for common schedules, and @reboot runs the job once when cron starts. A sixth field for seconds at the start, ? for “any day” and L for the last day of the month come from Quartz, Spring and similar schedulers, and ordinary crontab does not understand them.
Cron follows the computer’s local time. When summer time starts and the clock jumps from 2am to 3am, a job with a fixed time in the skipped hour runs straight after the change, and when the clocks go back it runs only once. Jobs with * in the minute or hour field follow the new clock instead. The list here works the same way, in your time zone or in UTC.
Check which implementation runs your schedule. Cloud services often have their own variants: AWS EventBridge, for example, has six fields with the year last and requires ? in either the day of the month or the day of the week, and many services work in UTC rather than local time.
The other way round, you can describe the schedule in words instead: “every 15 minutes”, “at 6am on weekdays”, “last day of the month at midnight”, “every Monday at 9” or “every 2 hours between 9 and 17”. Times are read as 9, 9.30, 9:30 and 09h30, ranges as 9–17 and lists as 1, 15. When the phrase is understood the expression appears straight away, and the explanation above says in words what it means, so you can see whether it says what you meant. When it is not understood, the words that could not be read are named rather than guessed at.
The builder below the text box does the same thing with controls instead of words, and the two stay in step: a phrase fills in the controls, and every change to the controls rewrites the expression. Not everything can be expressed in cron. There is no way to say “the first Monday of the month” or “every other week” in ordinary crontab, and two separate times in one phrase (9 and 17) are written as a list in the hour field: 0 9,17 * * *.