# Cron Syntax Reference
Cron expressions schedule recurring jobs — crontab, CI pipelines (GitHub Actions schedule:, GitLab CI), and most job schedulers all use the same 5-field format. This sheet covers the fields, the operators, and the schedules people actually search for.
* * * * *
| | | | |
| | | | +----- day of week (0-7, both 0 and 7 = Sunday)
| | | +------- month (1-12)
| | +--------- day of month (1-31)
| +----------- hour (0-23)
+------------- minute (0-59)
| Operator | Meaning | Example |
|---|---|---|
| `*` | Every value | `* * * * *` — every minute |
| `,` | Value list | `0,30 * * * *` — at :00 and :30 |
| `-` | Range | `9-17 * * * *` — hours 9 through 17 |
| `/` | Step | `*/15 * * * *` — every 15 minutes |
| combined | Range + step | `0-30/10 * * * *` — 0, 10, 20, 30 |
| String | Equivalent |
|---|---|
| `@yearly` / `@annually` | `0 0 1 1 *` |
| `@monthly` | `0 0 1 * *` |
| `@weekly` | `0 0 * * 0` |
| `@daily` / `@midnight` | `0 0 * * *` |
| `@hourly` | `0 * * * *` |
| `@reboot` | Run once at startup (not supported by all schedulers, e.g. GitHub Actions) |
Not every cron implementation supports these @ shortcuts — POSIX cron (the strict standard) doesn't, but cron on Linux (Vixie/cronie), GitLab CI, and most task queues do. GitHub Actions' schedule: accepts none of them — its parser only takes the 5-field numeric form, so cron: '@daily' in a workflow file is rejected outright.
*/15 * * * *
0 9 * * 1-5
1-5 is Monday through Friday. 0 and 7 both mean Sunday — don't assume 0 means Monday.
0 0 1 * *
0 6,18 * * *
*/10 9-17 * * 1-5
on:
schedule:
- cron: '0 3 * * *' # 03:00 UTC every day
GitHub Actions cron always runs in UTC regardless of repo settings, and scheduled workflows are silently disabled after 60 days of repository inactivity — a common "why did my nightly job stop running" cause.
0 0 15 * 5 means "midnight on the 15th, OR midnight on any Friday" — not "the 15th if it's a Friday." If you need both conditions true, most schedulers require app-level logic instead.0 and 7 both mean Sunday in the day-of-week field — a 1-7 range is nonsensical (7 duplicates 0) and some parsers reject it outright. fires every minute of the matched hour, not once:* 9 runs 60 times between 9:00 and 9:59, not once at 9am. The classic fix for "run once at 9am" is 0 9 .CRON_TZ/TZ env var if the scheduler supports it), but GitHub Actions and most hosted CI cron run strictly in UTC. A schedule that looks right locally can fire at the wrong wall-clock hour in production.