The expression
0 9,21 * * *
Runs at 09:00 and 21:00 every day: twice a day, 12 hours apart.
| Field | Value | Meaning |
|---|---|---|
| Minute | 0 |
at minute 0 |
| Hour | 9,21 |
at 9 a.m. and 9 p.m. |
| Day of month | * |
every day |
| Month | * |
every month |
| Day of week | * |
every day of the week |
A comma makes a list: the field matches any of the values. Any two hours work, and they don't have to be 12 hours apart: 0 8,17 * * * runs at 8:00 and 17:00. Every value in the hour list shares the same minute, though.
Variants
| Schedule | Expression |
|---|---|
| Midnight and noon | 0 0,12 * * * |
| 6:00 and 18:00 | 0 6,18 * * * |
| 8:00 and 17:00 on weekdays | 0 8,17 * * 1-5 |
| 8:30 and 17:00 (different minutes) | two lines: 30 8 * * * and 0 17 * * * |
| Three times a day (8, 14, 20) | 0 8,14,20 * * * |
| Once a day at 9:00 | 0 9 * * * |
| Every 6 hours | 0 */6 * * * |
When the two times need different minutes, cron can't combine them in one line: 30,0 8,17 * * * would run four times (8:00, 8:30, 17:00, 17:30), because every minute in the list pairs with every hour. Write two entries instead.
Where to write it
- crontab (Linux, macOS):
0 9,21 * * * /usr/local/bin/sync.shincrontab -e, in the server's time zone. - GitHub Actions:
on: schedule: - cron: '0 9,21 * * *'means 09:00 and 21:00 UTC. To get local times, convert each hour (for Berlin in summer, UTC+2, that's0 7,19 * * *). For two different minutes, GitHub accepts several- cron:entries underschedule:. - Kubernetes CronJob:
schedule: "0 9,21 * * *"withtimeZone:for local hours. One CronJob holds one schedule, so different minutes need two CronJobs. - AWS EventBridge:
cron(0 9,21 * * ? *), six fields with?in day of week. EventBridge rules are UTC; EventBridge Scheduler can take a time zone.
Common mistakes
0 9-21 * * *is every hour from 9:00 to 21:00, 13 runs. A dash is a range; a comma is a list.0,30 9 * * *runs at 9:00 and 9:30, twice in the same hour, not twice a day.- Spaces in the list.
0 9, 21 * * *has six fields and is rejected or misread. Lists never contain spaces. - Assuming the second run is 12 hours after the first finished. Cron is clock-based; a long 9:00 run doesn't move the 21:00 one.
Paste any expression into the Cron Expression Parser to see it in words and its next run times.