Cron Expression Syntax: A Complete Guide with Examples
Cron is the original Unix job scheduler, and its expression syntax has become a cross-platform standard for describing recurring schedules in CI/CD pipelines, cloud functions, database maintenance windows, and task queues. The syntax is compact but easy to misread — a single character mistake can cause a job to run every minute instead of once a day.
The five standard fields
A standard cron expression has five space-separated fields:
┌─────────────── minute (0–59) │ ┌───────────── hour (0–23) │ │ ┌─────────── day of month (1–31) │ │ │ ┌───────── month (1–12 or JAN–DEC) │ │ │ │ ┌─────── day of week (0–6, 0=Sunday, or SUN–SAT) │ │ │ │ │ * * * * *
Field values and special characters
| Character | Meaning | Example |
|---|---|---|
* | Every value in the field | * * * * * — every minute |
, | List of values | 0 9,17 * * * — 9 AM and 5 PM |
- | Range of values | 0 9-17 * * * — every hour 9 AM–5 PM |
/ | Step / interval | */15 * * * * — every 15 minutes |
? | No specific value (day fields only, Quartz/AWS) | 0 12 15 * ? |
L | Last day of month or week (Quartz) | 0 0 L * ? — last day of month |
W | Nearest weekday (Quartz) | 0 9 15W * ? |
# | Nth weekday of month (Quartz) | 0 9 ? * 2#1 — first Monday |
Common schedule patterns
| Expression | Meaning |
|---|---|
* * * * * | Every minute |
0 * * * * | Every hour (on the hour) |
0 0 * * * | Daily at midnight |
0 9 * * 1-5 | Weekdays at 9 AM |
0 0 * * 0 | Every Sunday at midnight |
0 0 1 * * | First day of every month |
0 0 1 1 * | Once a year, Jan 1st at midnight |
*/5 * * * * | Every 5 minutes |
30 8,20 * * * | 8:30 AM and 8:30 PM daily |
0 2 * * 6,0 | Weekends at 2 AM (Sat and Sun) |
Six-field cron (with seconds)
Some schedulers (Quartz, AWS EventBridge, GitHub Actions) add a sixth field for seconds or year. The order varies by platform:
# Quartz (seconds first) 0 0 12 * * ? → every day at noon # AWS EventBridge (seconds first, year last) 0 0 12 * * ? * → every day at noon
Always check which variant your platform uses — mixing up the field order is a common source of confusion.
Special strings (vixie cron and systemd)
Many cron implementations support named shortcuts instead of numeric expressions:
@yearly/@annually— equivalent to0 0 1 1 *@monthly— equivalent to0 0 1 * *@weekly— equivalent to0 0 * * 0@daily/@midnight— equivalent to0 0 * * *@hourly— equivalent to0 * * * *@reboot— run once at startup (vixie cron only)
Platform differences to watch for
- Sunday is 0 or 7 — vixie cron accepts both 0 and 7 as Sunday; some platforms only accept 0.
- Day of month + day of week interaction — in most cron implementations, if both are non-
*, the job runs when either condition is true (OR logic), not when both are true (AND). Quartz uses?to say "don't care" for one of them. - Timezone — cron traditionally runs in the server's local timezone. Cloud schedulers (AWS, GCP, GitHub Actions) let you specify a timezone explicitly — always do this for production jobs.
- GitHub Actions — uses UTC and the standard five-field format. Minimum interval is every 5 minutes.
Debugging tips
Before deploying a cron expression, run it through a parser that shows the next N execution times. A schedule that looks right in your head often has off-by-one errors in the day-of-week field (0 vs 7 for Sunday) or in step expressions (*/30 in the minute field runs at :00 and :30, not 30 minutes after the last run).
Try it yourself
Use the free browser-based Cron Expression Parser on DevBench — no signup, runs entirely in your browser.
Open Cron Expression Parser