GitHub Actions Schedule (cron) — 2026 Guide with Timezone & Reliability Fixes
GitHub Actions schedule triggers explained: UTC-only cron, why scheduled runs disappear after 60 days, how to add jitter, and the 12 patterns every QA pipeline needs.

2026-07-17 · By Avinash K
GitHub Actions' schedule trigger is the simplest way to run nightly regression, security scans, or dependency updates - but it has three quirks that bite every team: UTC-only, silent 60-day pause, and no built-in jitter. Here's how to use it well.
The minimum viable workflow
name: Nightly regression
on:
schedule:
- cron: '30 2 * * *' # 02:30 UTC every day
workflow_dispatch: # allow manual runs too
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright testQuirk #1 - UTC only, always
GitHub Actions ignores your repository, organisation, and runner timezone. Cron always fires in UTC. Convert first:
India 08:00 IST -> 02:30 UTC -> cron: '30 2 * * *'
US-East 09:00 EST -> 14:00 UTC -> cron: '0 14 * * *'
Europe 09:00 CET -> 08:00 UTC -> cron: '0 8 * * *'Daylight saving is on you - a 09:00 EST job becomes 09:00 EDT (one hour earlier UTC) in summer. Either accept the drift or pick UTC directly.
Quirk #2 - schedules pause after 60 days of no repo activity
If nobody pushes commits, opens issues, or triggers workflows for 60 days, GitHub disables scheduled workflows automatically. To keep a low-activity repo alive, add a weekly no-op push or a self-ping:
- name: Keepalive
uses: gautamkrishnar/keepalive-workflow@v2Quirk #3 - no jitter means every job on GitHub fires at :00
At exactly 0 * * * * GitHub's queue spikes and your job can be delayed by 5-20 minutes. Spread your schedules to odd minutes:
# Bad - everyone picks this
- cron: '0 * * * *'
# Good - you're one of few on minute 17
- cron: '17 * * * *'12 patterns every QA pipeline needs
Every hour on the :17 17 * * * *
Every 30 min, business hours (UTC) */30 8-18 * * 1-5
Nightly regression at 02:30 UTC 30 2 * * *
Weekly Monday 06:00 UTC report 0 6 * * 1
First of month, midnight UTC 0 0 1 * *
Twice daily 08:00 and 20:00 UTC 0 8,20 * * *
Every 6 hours 0 */6 * * *
Weekdays only, 09:15 UTC 15 9 * * 1-5
Weekend only, 07:00 UTC 0 7 * * 6,0
Every 15 min */15 * * * *
Quarterly (Jan/Apr/Jul/Oct 1st) 0 0 1 1,4,7,10 *
Once a year - Jan 1st, 00:00 UTC 0 0 1 1 *Verify before you push
Getting the UTC conversion wrong is the #1 source of "why didn't my nightly run?" tickets. Paste your expression into the Cron Expression Builder & Tester, switch the timezone to UTC, and confirm the next 10 run times before you commit the workflow. It also has a one-click "GitHub Actions" export that emits the full on: schedule: block.