# Scheduled Workflows — GitHub Actions

Source: https://www.skillbyai.com/en/github-actions/t-cron

> Cron in UTC.

## Five-field cron, best effort

The `schedule` trigger uses five-field cron syntax in **UTC**. Scheduled runs use the default branch's workflow file, can be delayed during busy periods, and are disabled automatically in public repositories after a long period without activity. Use schedules for nightly builds, dependency audits and cleanup. Avoid the top of the hour, when load is highest, and make scheduled jobs idempotent.

## Errors caught by actionlint, run

I checked this workflow with actionlint 1.7.12 (`actionlint -oneline .github/workflows/broken.yml`); the output and exit code are copied from that run. actionlint validates syntax, expressions, job dependencies and known actions offline; shellcheck was not installed, so shell scripts inside run: were not linted. The workflow was not executed on GitHub. actionlint finds three mistakes: hour 25 in the cron expression, a misspelled matrix property (nodee), and a needs: reference to a job that does not exist (biuld).

```yaml
name: Broken

on:
  schedule:
    - cron: "0 25 * * *"

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [20, 22]
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.nodee }}
  deploy:
    needs: biuld
    runs-on: ubuntu-latest
    steps:
      - run: echo deploying
```

Output:

```
.github/workflows/broken.yml:5:13: invalid CRON format "0 25 * * *" in schedule event: end of range (25) above maximum (23): 25 [events]
.github/workflows/broken.yml:16:29: property "nodee" is not defined in object type {node: number} [expression]
.github/workflows/broken.yml:17:3: job "deploy" needs job "biuld" which does not exist in this workflow [job-needs]
(exit code 1)
```

## Convert to UTC

A 09:00 IST job is 03:30 UTC: write "30 3 * * *".

**Quiz:** Which time zone do GitHub Actions cron schedules use?

- [ ] US Pacific time
- [ ] The repository owner's local time
- [ ] The runner's local time
- [x] UTC

*Answer:* UTC. Always UTC.
