Home › GitHub Actions Cron
GitHub Actions Cron: Schedule Workflows
How to schedule GitHub Actions workflows using cron expressions. Covers the schedule trigger syntax, timezone configuration, common examples and why your GitHub Actions cron is not running or not triggering.
GitHub Actions Cron Schedule Syntax
GitHub Actions uses the schedule event with POSIX cron syntax to run workflows at fixed intervals.
Add it to the on: block of your workflow YAML file.
Official reference: GitHub Docs - Events that trigger workflows.
name: Scheduled Workflow
on:
schedule:
- cron: '0 2 * * *' # Every day at 2:00 AM UTC
jobs:
run-task:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run scheduled task
run: echo "Running scheduled job"
GitHub Actions always uses UTC
All GitHub Actions scheduled workflows run in UTC regardless of your repository location or account timezone.
If you need to run at 9 AM CET (UTC+1), schedule at 0 8 * * *. If you need 9 AM CEST (UTC+2, summer), schedule at 0 7 * * *.
Since GitHub Actions 2024 you can optionally specify a timezone - see the timezone section below.
Cron Syntax for GitHub Actions
GitHub Actions uses standard 5-field POSIX cron syntax - the same as Linux crontab. Fields left to right:
* * * * * │ │ │ │ │ │ │ │ │ └── Day of week (0-6, Sunday=0, or SUN-SAT) │ │ │ └──── Month (1-12) │ │ └────── Day of month (1-31) │ └──────── Hour (0-23, UTC) └────────── Minute (0-59)
Minimum interval is every 5 minutes. * * * * * (every minute) is rejected.
GitHub recommends not scheduling workflows at the start of a popular hour (e.g. 0 * * * *) because load is highest then - use an offset like 17 * * * * instead.
GitHub Actions Cron Schedule Examples
| Expression | Description | UTC note |
|---|---|---|
'*/5 * * * *' | Every 5 minutes (minimum interval) | |
'0 * * * *' | Every hour | |
'0 2 * * *' | Daily at 2:00 AM | UTC |
'30 8 * * *' | Daily at 8:30 AM | UTC = 9:30 AM CET |
'0 9 * * 1-5' | Weekdays at 9:00 AM | UTC |
'0 0 * * 0' | Every Sunday at midnight | UTC |
'0 0 1 * *' | First day of every month | UTC |
'30 5,17 * * *' | Twice daily at 5:30 and 17:30 | UTC |
'0 0 * * 1' | Every Monday at midnight | UTC |
'0 2 * * 1,3,5' | Monday, Wednesday, Friday at 2 AM | UTC |
Multiple Schedules in One Workflow
You can define multiple cron entries under schedule - the workflow runs on any of them:
on:
schedule:
- cron: '0 8 * * 1-5' # Weekdays at 8:00 AM UTC
- cron: '0 12 * * 6,0' # Weekends at 12:00 PM UTC
GitHub Actions Cron Timezone
By default, GitHub Actions cron runs in UTC. Since late 2024, GitHub supports an optional timezone field under the schedule event.
Check the current GitHub Docs for availability on your plan.
on:
schedule:
- cron: '0 9 * * 1-5'
timezone: 'Europe/Madrid' # Run at 9 AM Madrid time
If your GitHub version does not support the timezone field, convert your schedule to UTC manually:
| Your local time | Timezone | UTC equivalent | Cron expression |
|---|---|---|---|
| 9:00 AM | CET (UTC+1) | 8:00 AM | '0 8 * * *' |
| 9:00 AM | CEST (UTC+2, summer) | 7:00 AM | '0 7 * * *' |
| 9:00 AM | EST (UTC-5) | 2:00 PM | '0 14 * * *' |
| 9:00 AM | PST (UTC-8) | 5:00 PM | '0 17 * * *' |
| 9:00 AM | JST (UTC+9) | 12:00 AM | '0 0 * * *' |
GitHub Actions Cron Not Running - Causes and Fixes
GitHub Actions cron is the most common source of "why is my schedule not working" questions. There are several causes specific to GitHub that do not apply to Linux cron.
GitHub delays scheduled runs
GitHub does not guarantee scheduled workflows run at the exact cron time. During periods of high load, runs can be delayed by 15 minutes or more. This is documented behavior - if your workflow ran 20 minutes late, this is the most likely cause. For time-critical jobs, GitHub Actions cron is not the right tool.
Schedule only runs on the default branch
GitHub Actions schedule only triggers on the repository's default branch (usually main or master).
If the workflow YAML is only in a feature branch, it will never run on a schedule.
Move the workflow file to the default branch.
GitHub disables schedules on inactive repos
GitHub automatically disables scheduled workflows in repositories with no activity for 60 days. You will receive an email before this happens. To re-enable, go to Actions › your workflow › Enable workflow. This is the most surprising cause and affects many open source projects.
Forks do not run scheduled workflows
By default, GitHub does not run schedule triggers on forked repositories.
The workflow must be explicitly enabled in the fork: go to Actions tab and click "Enable GitHub Actions".
Even then, the schedule runs on the fork's default branch only.
Actions disabled in repository settings
Go to Settings › Actions › General and confirm that Actions are enabled.
If Actions are disabled or restricted to specific workflows, scheduled runs will not fire.
Also check that the workflow file is not in a .github/workflows/ folder excluded by your settings.
Wrong cron expression
GitHub Actions uses 5-field POSIX cron - not 6-field Quartz syntax. A Quartz expression like 0 0 9 * * MON-FRI (6 fields) is invalid in GitHub Actions.
Also, * * * * * (every minute) is rejected - minimum is */5 * * * *.
Use the cron expression validator to check your expression.
How to Test a GitHub Actions Schedule Without Waiting
Waiting for the cron to fire to test your workflow is slow. Two faster approaches:
Add workflow_dispatch alongside schedule
on:
schedule:
- cron: '0 2 * * *'
workflow_dispatch: # allows manual trigger
With workflow_dispatch you can trigger the workflow manually from the Actions tab at any time. Use this to test the workflow logic before relying on the schedule.
Use a short interval temporarily
on:
schedule:
- cron: '*/5 * * * *' # every 5 min for testing
# - cron: '0 2 * * *' # production schedule (commented)
Temporarily set the cron to */5 * * * * and push to the default branch. Within 5-10 minutes you will see whether it fires. Restore the original schedule when done.
Combine Schedule with Other Triggers
A workflow can have multiple triggers. Common pattern: run on push during development, and on schedule in production:
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 2 * * *'
workflow_dispatch:
GitHub Actions Cron Limits
| Limit | Value | Notes |
|---|---|---|
| Minimum interval | Every 5 minutes | */5 * * * * is the shortest valid schedule |
| Timing guarantee | None | Runs may be delayed 15+ minutes during peak load |
| Branch | Default branch only | Workflow file must be on main or master |
| Inactivity disable | 60 days | GitHub disables schedules on inactive repos |
| Free tier minutes | 2,000 min/month | For public repos, minutes are unlimited |
| Timezone | UTC (default) | Optional timezone field available since 2024 |
Build and validate your GitHub Actions cron expression
GitHub Actions uses standard 5-field Linux cron syntax. Generate it here and paste it directly into your workflow YAML.