Cheatsheet

Cron Syntax Reference

# 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.

Quick reference

The 5 fields

* * * * *
| | | | |
| | | | +----- day of week (0-7, both 0 and 7 = Sunday)
| | | +------- month (1-12)
| | +--------- day of month (1-31)
| +----------- hour (0-23)
+------------- minute (0-59)

Operators

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

Named strings (Vixie cron / most modern schedulers)

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.

Common patterns

Every 15 minutes

*/15 * * * *

Every weekday at 9am

0 9 * * 1-5

1-5 is Monday through Friday. 0 and 7 both mean Sunday — don't assume 0 means Monday.

Midnight on the 1st of every month

0 0 1 * *

Twice a day, 6am and 6pm

0 6,18 * * *

Every 10 minutes, business hours only, weekdays

*/10 9-17 * * 1-5

GitHub Actions workflow schedule (UTC only)

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.

Pitfalls

  • Day-of-month AND day-of-week together is OR, not AND: 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.
  • *Minute-field 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 .
  • Timezone assumptions bite hard: crontab uses the system's local timezone (or 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.
  • Scheduled CI jobs aren't guaranteed to run exactly on time: most hosted runners (GitHub Actions included) queue scheduled jobs and can delay them by minutes during high load — don't build sub-minute-precision logic on cron alone.

Related ZipKit tools

Related cheatsheets

  • Git Commands Cheatsheet — the version control side of the deploy pipelines cron jobs usually trigger.
  • .htaccess Cheatsheet — Apache config for the servers those cron jobs run on.