SoftwareTestPilot
Automation TestingPublished: 8 min read

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.

Avinash K
Founder & QA Engineer at SoftwareTestPilot
Share:XLinkedInWhatsApp
GitHub Actions schedule cron workflow YAML example
GitHub Actions schedule cron workflow YAML example

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 test

Quirk #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@v2

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

Frequently asked questions

1.Can GitHub Actions run more often than every 5 minutes?
In practice no. GitHub documents a minimum interval of 5 minutes and the scheduler often coalesces frequent jobs during high load. For sub-minute cadence use an external scheduler that calls repository_dispatch.
2.Why did my scheduled workflow stop firing?
Most likely the 60-day inactivity pause. Push a commit or manually re-enable the workflow in the Actions tab. A keepalive action prevents recurrence.
3.Can I have multiple schedules in one workflow?
Yes - list multiple - cron: entries under schedule:. Each entry triggers an independent workflow run, and you can branch behavior on github.event.schedule.
4.How do I test a schedule without waiting?
Add workflow_dispatch: to the on: block. That gives you a manual 'Run workflow' button you can hit while iterating.