Skip to main content

GitHub Actions and Cron: A Powerful Duo

GitHub Actions · Cron · Automation

GitHub Actions and Cron: A Powerful Duo

Core use

Run workflows automatically on a schedule without needing a push or manual trigger.

Main constraint

GitHub Actions cron schedules are evaluated in UTC, not in your local timezone.

Best habit

Add workflow_dispatch so you can test scheduled workflows without waiting for the next cron run.

Introduction

GitHub Actions lets you automate repetitive tasks directly from your repository. That can mean running tests, publishing reports, deploying code, or handling small maintenance jobs on a fixed schedule.

One of the most useful triggers for that is cron scheduling. Instead of waiting for a push, pull request, or manual run, you can tell GitHub to run a workflow at a defined interval.

This is simple once the pieces click: a workflow file, an on.schedule trigger, and a cron expression that says when the automation should fire.

Setup

Setting Up a Scheduled Workflow

Workflow files live inside the .github/workflows/ directory of your repository. The on section defines what triggers the workflow.

name: Daily Report

on:
  schedule:
    - cron: '0 9 * * *'   # every day at 9:00 AM UTC

jobs:
  run-report:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Run report script
        run: python generate_report.py

All cron schedules in GitHub Actions are evaluated in UTC. If you want the workflow to run at a local time, you need to convert that time into UTC yourself.

Important GitHub Actions does not let you set a timezone directly for on.schedule. You must account for the UTC offset manually.
Syntax

Reading Cron Expressions

A GitHub Actions cron expression uses five fields:

# ┌─────────── minute        (0–59)
# │ ┌───────── hour          (0–23, UTC)
# │ │ ┌─────── day of month  (1–31)
# │ │ │ ┌───── month         (1–12)
# │ │ │ │ ┌─── day of week   (0–6, Sunday = 0)
# │ │ │ │ │
  * * * * *

A * means “every value for that field.”

Expression Meaning
0 0 * * * Every day at midnight UTC
0 9 * * * Every day at 9:00 AM UTC
30 15 * * 1-5 3:30 PM UTC, Monday through Friday
0 0 * * 0 Every Sunday at midnight UTC
0 0 1 * * First day of every month at midnight UTC
*/15 * * * * Every 15 minutes
0 8,17 * * 1-5 8:00 AM and 5:00 PM UTC on weekdays
Helpful habit Check any cron expression in crontab.guru before you trust it in production.
Combining triggers

Combining Schedule with Other Triggers

A scheduled workflow does not have to rely on cron alone. A common pattern is to combine schedule with push or workflow_dispatch.

on:
  schedule:
    - cron: '0 9 * * *'
  push:
    branches:
      - main
  workflow_dispatch:

This makes the workflow easier to test. You do not need to wait until the next scheduled time just to see whether it works.

The manual run button from workflow_dispatch is one of the easiest ways to debug a scheduled workflow.

Multiple schedules

Using More Than One Schedule

You can define multiple cron expressions for the same workflow when different days need different timing.

on:
  schedule:
    - cron: '0 9 * * 1-5'    # weekdays at 9 AM UTC
    - cron: '0 12 * * 0,6'   # weekends at noon UTC

This is useful when a workflow should run more often during the week and differently on weekends.

Limitations

Important Limits and Gotchas

  • Scheduled workflows are disabled after 60 days of inactivity in public repositories.
  • Timing is approximate. GitHub may run scheduled workflows later than expected during high load.
  • The shortest supported interval is 5 minutes.
  • Scheduled workflows run from the default branch.
Production mindset Do not use scheduled workflows for timing that must be exact to the minute. GitHub Actions scheduling is reliable for routine automation, not precision orchestration.
Example

A Practical Example: Weekly Dependency Check

name: Weekly Dependency Check

on:
  schedule:
    - cron: '0 8 * * 1'    # every Monday at 8:00 AM UTC
  workflow_dispatch:

jobs:
  check-dependencies:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install pip-outdated
        run: pip install pip-outdated

      - name: Check for outdated packages
        run: pip-outdated requirements.txt

This is a good example of routine automation: a predictable weekly check that also remains manually runnable when needed.

FAQ

Frequently Asked Questions

These are the practical questions people usually have when they first start using cron in GitHub Actions.

Are GitHub Actions cron schedules based on my local timezone?

No. Scheduled workflows use UTC, so local-time runs must be converted manually.

What is the shortest interval GitHub Actions allows?

The shortest supported schedule is once every 5 minutes.

Do scheduled workflows run exactly on time?

Not always. They can run later than expected, especially during periods of high GitHub load.

Why should I add workflow_dispatch to a scheduled workflow?

Because it gives you a manual run button, which makes testing and debugging much easier.

Can one workflow have more than one cron schedule?

Yes. You can list multiple cron expressions under schedule.

What branch does a scheduled workflow run from?

Scheduled workflows run from the repository’s default branch.

What happens if a repository sits inactive for a long time?

In a public repository, scheduled workflows can be automatically disabled after 60 days of inactivity.

What is the simplest beginner rule here?

Verify the cron expression, remember everything is UTC, and always add a manual trigger for testing.

Conclusion

Cron scheduling in GitHub Actions is straightforward once you understand the five-field syntax and the UTC-only rule.

The biggest habits worth keeping are simple: verify cron expressions before you trust them, add workflow_dispatch so you can test manually, and remember that scheduled workflows are reliable for recurring automation but not for exact second-level timing.

With those boundaries in mind, scheduled workflows are one of the easiest ways to automate recurring repository tasks without building extra infrastructure.

Raell Dottin

Comments