How Cron Expressions Work
Cron expressions look cryptic but follow a small, consistent grammar. This guide walks through the five fields of a standard cron expression, explains the special characters, and shows the patterns you'll write most often — plus the edge cases that trip up even experienced engineers.
Updated
Anatomy of a cron expression
A cron expression is a single line of text with five space-separated fields. Each field controls one unit of time:
* * * * *
│ │ │ │ │
│ │ │ │ └── day of week (0–6, Sun=0)
│ │ │ └──── month (1–12)
│ │ └────── day of month (1–31)
│ └──────── hour (0–23)
└────────── minute (0–59)
A literal asterisk * means “every valid value for this field.” So * * * * * means “every minute of every hour of every day of every month, every day of the week” — the most frequent schedule possible in standard cron.
The five fields
| Field | Range | Example | Meaning |
|---|---|---|---|
| Minute | 0–59 | 30 | At minute 30 |
| Hour | 0–23 | 14 | At 2 PM |
| Day of month | 1–31 | 1 | On the 1st of the month |
| Month | 1–12 or JAN–DEC | 3 or MAR | In March |
| Day of week | 0–6 or SUN–SAT | 1 or MON | On Monday |
Day-of-week 0 is Sunday in Unix and Kubernetes. Quartz and EventBridge use 1 for Sunday and 7 for Saturday. Spring accepts both 0 and 7 as Sunday.
Special characters
Beyond literal numbers and *, four characters appear in every cron dialect:
- Comma
,— list multiple values.0,15,30,45in the minute field means “at :00, :15, :30, and :45.” - Hyphen
-— range of values.1-5in the day-of-week field means “Monday through Friday.” - Slash
/— step value.*/15in the minute field means “every 15th minute starting from 0” (i.e., :00, :15, :30, :45).2/10starting from 2 means :02, :12, :22, :32, :42, :52. - Asterisk
*— every value.
Quartz, AWS EventBridge, and a handful of other dialects add more characters: ? (no specific value), L (last day of month/week), W (weekday nearest a given day), and # (the nth occurrence of a weekday in a month). See the Cron Dialect Comparison for the full list.
Common patterns
| Expression | Meaning |
|---|---|
* * * * * | Every minute |
*/5 * * * * | Every 5 minutes |
0 * * * * | Every hour, on the hour |
0 0 * * * | Every day at midnight (00:00) |
0 9 * * 1-5 | At 9 AM on weekdays (Mon–Fri) |
0 0 1 * * | At midnight on the 1st of every month |
0 0 * * 0 | At midnight every Sunday |
0 12 * * 6,0 | At noon on weekends (Sat + Sun) |
30 14 1,15 * * | At 2:30 PM on the 1st and 15th of every month |
Gotchas worth knowing
The day-of-month vs day-of-week OR trap. If both fields are set to anything other than *, the job runs on days that match either field — not both. So 0 0 1 * 1 runs at midnight on the 1st of every month and every Monday. To run “on the 1st only if it’s a Monday,” you have to gate it inside your script. See the DOM/DOW trap guide for details.
Daylight saving time. Traditional Unix cron uses the system’s local timezone, which causes a daily job scheduled at 2:30 AM to skip on spring-forward day and run twice on fall-back day. Always set CRON_TZ=UTC at the top of your crontab if your workload spans timezones. Kubernetes CronJob defaults to UTC unless spec.timeZone is set.
Minimum granularity is one minute. Cron cannot fire more often than once per minute. For sub-minute scheduling, use a long-running process with an in-process scheduler (e.g. setInterval, time.Tick, asyncio.sleep), a job queue (Celery, Sidekiq), or systemd timers with OnUnitActiveSec=30s.
Overlapping runs. Most cron daemons happily spawn a new instance while the previous one is still running. If your job can take longer than the interval, guard with a lockfile (flock), set concurrencyPolicy: Forbid on Kubernetes CronJobs, or pick a longer interval.
Frequently asked questions
How many fields does a cron expression have?
What is the smallest interval cron can express?
Related
Every 5 Minutes
`*/5 * * * *` — the most common cron pattern.
ToolCron Parser
Paste any expression and see it explained in plain English.
GuideCron Dialect Comparison
How Unix, Quartz, Kubernetes, EventBridge, Spring, and GitHub Actions differ.
GuideThe DOM / DOW OR Trap
Why setting both day-of-month and day-of-week behaves unexpectedly.