CronPup

← Guides

Monitoring GitHub Actions scheduled workflows (cron) for missed and failed runs

The schedule: trigger in GitHub Actions is convenient for nightly jobs, but it has caveats that catch people out:

None of these produce an alert anyone sees. A heartbeat does.

Add a heartbeat step

Store the ping URL as a repository secret (here CRONPUP_URL). Then ping on success and on failure:

name: nightly-export
on:
  schedule:
    - cron: "17 3 * * *"     # avoid :00, which is the most congested minute
  workflow_dispatch:

jobs:
  export:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./scripts/export.sh

      - name: Heartbeat (success)
        if: success()
        run: curl -fsS -m 10 --retry 3 "${{ secrets.CRONPUP_URL }}"

      - name: Heartbeat (failure)
        if: failure()
        run: curl -fsS -m 10 --retry 3 "${{ secrets.CRONPUP_URL }}/fail"

Set a generous grace period

Because scheduled runs can start late, use the same cron expression in CronPup (timezone UTC) and a grace period of 30–60 minutes. The heartbeat then catches the real problems (disabled workflows, persistent failures) without alerting on ordinary queue delays.

Monitor your scheduled workflows. The free plan covers 10.