GitHub Actions Cron Helper
Compose a correct on.schedule cron for GitHub Actions — local time to UTC, DST duality, next runs and YAML — entirely on this device.
The plain-English schedule appears here as you type.
Cron (UTC)—
| Run | UTC | In UTC |
|---|---|---|
| 1 | — | — |
| 2 | — | — |
| 3 | — | — |
| 4 | — | — |
| 5 | — | — |
| Phase | UTC offset | Cron (UTC) | Local meaning |
|---|---|---|---|
| — | |||
Press ? for shortcuts
Do it offline:$ systemd-analyze calendar --iterations=5 '*-*-* 08:00:00 UTC'
How to use it
- Pick a tab: paste a 5-field cron expression, or enter a local time plus an IANA zone.
- Read the sentence — it is always the UTC meaning, the only clock GitHub schedules against.
- Check the next five runs, and the winter and summer rows when your zone observes daylight saving.
- Apply the advisories: one-click macro fixes, and an off-peak minute when the schedule sits on the top of the hour.
- Copy or download the workflow YAML and commit it to the default branch — the only branch on.schedule reads.
GitHub Actions runs every on.schedule cron in UTC, with no timezone setting to change that. Enter the local wall time you actually care about, pick an IANA zone, and the helper derives the UTC expression, shows what it means in winter and in summer, lists the next five runs, and writes the workflow YAML. All derivation happens on this device; nothing you type is uploaded.
Examples
09:00 Europe/Berlincron 0 8 * * *
sentence At 08:00 UTC
next runs 2026-08-04 08:00 UTC · 2026-08-05 08:00 UTC · 2026-08-06 08:00 UTC
winter '0 8 * * *' — 09:00 Europe/Berlin (UTC+01:00)
summer '0 7 * * *' — 10:00 Europe/Berlin (UTC+02:00)
off-peak 7 8 * * *09:00 in Berlin is 08:00 UTC only under winter time; between the last Sundays of March and October the same expression fires at 10:00 local. Both readings sit in the duality rows, and the dual-cron snippet under the table pins 09:00 year-round with a guard step.
*/15 * * * *cron */15 * * * *
sentence Every 15 minutes UTC
next runs 2026-08-04 00:15 UTC · 2026-08-04 00:30 UTC · 2026-08-04 00:45 UTCInterval schedules dodge the daylight-saving question — every quarter hour is every quarter hour in any zone. The timetable is still best-effort: at peak load a tick can start late or be skipped.
0 0 * * *cron 0 0 * * *
sentence At 00:00 UTC
next runs 2026-08-05 00:00 UTC · 2026-08-06 00:00 UTC · 2026-08-07 00:00 UTC
off-peak 30 2 * * *The start of every hour is the high-load window GitHub itself warns about. The advisory proposes 30 2 * * * — derived deterministically from the expression, so every visitor pasting this cron sees the same rewrite.
09:00 Asia/Kolkatacron 30 3 * * *
sentence At 03:30 UTC
next runs 2026-08-04 03:30 UTC · 2026-08-05 03:30 UTC · 2026-08-06 03:30 UTC
fixed '30 3 * * *' — 09:00 Asia/Kolkata (UTC+05:30)India Standard Time is UTC+05:30 all year, so the table collapses to a single fixed row and the half hour lands in the minute field: 09:00 IST is 03:30 UTC, never 03:00 or 04:00.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Schedules pause after 60 idle days
On public repositories, GitHub disables a scheduled workflow once the repository has seen no activity for 60 days — runs simply stop appearing. Re-enable it from the Actions tab.
Only the default branch is scheduled
on.schedule triggers from the workflow file on the default branch. A cron edited on a feature branch takes effect at merge time — why a freshly corrected schedule can keep firing at the old minute.
Pair schedule with workflow_dispatch
Every snippet here attaches workflow_dispatch: {}, so the job can also be started by hand from the Actions tab — the fastest way to test a scheduled workflow without waiting for its next tick.
Early local mornings are UTC yesterday
East of Greenwich, converting a small local hour can cross midnight: 00:30 in Kolkata is 19:00 UTC on the previous day. A day-shift note names the boundary whenever the derived cron lives on a different UTC date.
@reboot has no equivalent
Six vixie macros translate to plain five-field crons, and the error hands you that rewrite. @reboot does not — nothing boots — so the honest substitutes are the push and workflow_dispatch triggers.
Drift means late or skipped, never early
Under load the schedule event is delayed or dropped for that tick; it never fires ahead of its cron time. Point monitors at whether the 08:00 run happened by 08:30, not at exact start minutes.
Common errors
GitHub Actions supports only 5-field cron — `@daily` → `0 0 * * *`- All seven vixie shorthands are outside the Actions grammar. The message carries the literal five-field equivalent, ready to apply — only @reboot offers none.
Looks like Quartz (seconds field) — 6 fields. GitHub Actions cron has exactly 5; drop the leading seconds field.- Six or seven fields is the Quartz shape, seconds first. GitHub reads exactly five — drop the extras here, or switch to the Quartz page for that dialect.
field 2 (hour): `32` out of range 0–23- Field errors are position-anchored: the 1-based field number, its name, and the token that failed. Hours run 0 through 23, so 8 pm is 20.
GitHub's minimum schedule interval is 5 minutes — this expression schedules runs as little as 4 minutes apart.- A tighter step than the five-minute floor will not run as written. Widen the interval to at least */5 so the committed timetable matches what GitHub can deliver.
Expression is longer than the 1,024-character limit for this tool. A GitHub Actions cron is 5 short fields — check next runs from your shell instead: systemd-analyze calendar --iterations=5 '*-*-* 08:00:00 UTC'- A schedule expression is five short tokens, so oversized input is refused whole instead of being truncated into some other schedule. The systemd line previews occurrences from a Linux shell.
FAQ
Why is my GitHub Actions cron not running?
Check three things. Load: schedule is best-effort and the top of each hour is its high-load window, so a run may start late or be skipped — move off minute 0. Inactivity: on public repositories the schedule is disabled after 60 days without repository activity. Branch: only the workflow file on the default branch triggers, so an edit elsewhere has not taken effect yet.
What timezone does GitHub Actions cron use?
UTC, and it cannot be changed: on.schedule accepts no timezone parameter, and setting TZ inside the job affects the shell, never the trigger. Write the expression in UTC and keep both local readings beside it — the layout this page renders.
How do I run a workflow at 9 am local time?
Two honest options. Accept the shift: schedule the winter-phase UTC cron and let summer runs land an hour later on the local clock. Or pin the hour: use the dual-cron snippet, which registers both phase crons and adds a guard step keeping only the run where your zone's clock reads 09 — the twin exits immediately.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Re-run the current schedule immediately against a fresh clock.
- ⌘/Ctrl + S
- Download the generated snippet as workflow.yml.
- ⌘/Ctrl + C
- With no text selected, copy the on.schedule YAML.
- ⌘/Ctrl + Shift + C
- Copy the YAML even while text is selected.
- t
- Cycle the theme (ignored while an input has focus).
- ? or ⌘/Ctrl + /
- Show the shortcut overlay.
- Esc
- Dismiss the topmost dialog.