Crontab Syntax Reference
Crontab syntax is five fields separated by spaces: minute, hour, day of month, month and day of week. This page is the reference for what each field accepts and how they combine.
The short answer
Crontab syntax is minute hour day-of-month month day-of-week, five fields separated by spaces. In a crontab file the command follows on the same line.
# ┌───────────── minute (0-59)
# │ ┌─────────── hour (0-23)
# │ │ ┌───────── day of month (1-31)
# │ │ │ ┌─────── month (1-12 or JAN-DEC)
# │ │ │ │ ┌───── day of week (0-7 or SUN-SAT; 0 and 7 are Sunday)
# │ │ │ │ │
# * * * * * command to runAn asterisk means every value, a comma lists values, a hyphen gives a range and a slash gives a step.
Check a crontab schedule
Paste the five time fields of a crontab line, without the command, to see what each one resolves to.
The five cron expression fields
Standard cron has exactly five time fields. Their order never changes, and each one accepts a single value, a list, a range, a step, or *.
| Field | Range | Names | Notes |
|---|---|---|---|
| Minute | 0-59 | none | Which minute of the hour. |
| Hour | 0-23 | none | 24-hour clock. 0 is midnight. |
| Day of month | 1-31 | none | Months with fewer days skip days that do not exist. |
| Month | 1-12 | JAN-DEC | Names are three letters, case does not matter. |
| Day of week | 0-7 | SUN-SAT | 0 and 7 are both Sunday on Linux. POSIX defines 0-6 only. |
Some systems add a field: a leading seconds field (Quartz and Spring) or a trailing year field (AWS EventBridge, optional in Quartz). If an expression has six fields, check which of those it is before reading it.
How the fields combine
For a run to happen, the minute, hour and month must match, and so must the day. The day rule has one surprise. When both day-of-month and day-of-week are restricted, classic cron runs the job when either one matches. POSIX describes this directly: a day matches if it satisfies the day of month or the day of week.
For example 0 9 15 * 1 is read as: Runs at 9:00 AM on day 15 of every month and every Monday (either one triggers a run).
If you wanted Mondays that fall on the 15th, plain cron cannot say it. Schedule the day-of-week and test the date inside the job. Other systems treat the pair differently: Vercel rejects it, and EventBridge and Quartz make you put ? in one of the two fields.
Operators: asterisk, comma, hyphen and slash
These four work in every field of every platform covered here.
| Symbol | Meaning | Example | Reads as |
|---|---|---|---|
* | every value in the field | 0 * * * * | Runs every hour, on the hour. |
, | a list of values | 0 9,17 * * * | Runs at 9:00 AM and 5:00 PM every day. |
- | an inclusive range | 0 9-17 * * * | Runs every hour from 9:00 AM to 5:00 PM. |
/ | a step through a range or * | */15 * * * * | Runs every 15 minutes. |
The slash has details worth knowing, such as steps that do not divide the field evenly. They are in the cron special characters reference.
Names and macros
Months and weekdays can be written as three-letter names, for example JAN-MAR or MON-FRI. Names are not accepted on Vercel. Macros are a Vixie-cron extension, not part of POSIX, and support varies: Kubernetes accepts the five time macros, GitHub Actions documents that it does not support them, and EventBridge and Quartz have no equivalent.
| Macro | Same as | Meaning |
|---|---|---|
@hourly | 0 * * * * | start of every hour |
@daily or @midnight | 0 0 * * * | every day at midnight |
@weekly | 0 0 * * 0 | midnight on Sunday |
@monthly | 0 0 1 * * | midnight on the 1st |
@yearly or @annually | 0 0 1 1 * | midnight on January 1 |
@reboot | not a time | once when the cron daemon starts |
Where the fields sit in a crontab file
In a personal crontab the five fields are followed by the command: 15 3 * * * /usr/local/bin/backup.sh. System crontabs, such as /etc/crontab and the files in /etc/cron.d, add a user name between the fields and the command. The Linux crontab guide explains how to install, list and debug these files.
Crontab syntax across platforms
The core is shared, but field counts and weekday numbers differ. Always check which row applies before pasting an expression.
| Platform | Fields | Weekday numbers | Guide |
|---|---|---|---|
| Linux and Unix cron | 5 | 0-7 (cronie), 0-6 (POSIX), or names | Linux crontab guide |
| Kubernetes CronJob | 5 | 0-6 or names | Kubernetes cron expression guide |
| GitHub Actions | 5 | 0-6 or SUN-SAT | GitHub Actions cron guide |
| Vercel | 5 | 0-6, no names | Vercel cron guide |
| AWS EventBridge | 6, ending with a year | 1-7 (1 is Sunday) or names | AWS cron expression guide |
| Quartz (Java) | 6 or 7, starting with seconds | 1-7 (1 is Sunday) or names | Quartz cron expression guide |
| Spring (Java) | 6, starting with seconds | 0-7 (0 and 7 are Sunday) or names | Spring and Quartz differences |
Common crontab syntax mistakes
- Putting
*in the minute field by accident.* */2 * * *runs: Runs every minute during 12 AM, 2 AM, 4 AM, 6 AM, 8 AM, 10 AM, 12 PM, 2 PM, 4 PM, 6 PM, 8 PM and 10 PM hours. Use0 */2 * * *to run every two hours. - Writing six fields on a five-field system. Seconds-first syntax from Quartz or Spring is rejected by Linux, Kubernetes, GitHub Actions and Vercel.
- Using
%in the command. In a Linux crontab an unescaped percent sign ends the command and starts its standard input. Write\%. - Counting Sunday as 7 everywhere. Linux accepts it, but Vercel and many libraries expect 0 to 6.
Sources and further reading
Use a tool
Try the schedule from this page in a tool.