GitHub Actions Scheduled Workflows

Monitor GitHub Actions scheduled workflows.

Get alerted when a scheduled GitHub Actions workflow misses its expected heartbeat. Set a schedule and grace period, install a heartbeat after the required work, and verify your first run. Start with five free monitors, no credit card required.

5 monitors free · No credit card · Verify your first check-in

Example: a nightly backup workflow

  1. Work finishes

    Send a success heartbeat after the backup and required upload finish.

  2. A check-in is missed

    PingCron flags the missing heartbeat after its grace period and sends an alert to your configured destination.

  3. You investigate

    Check the GitHub run and backup destination. A heartbeat does not prove the backup is restorable.

Illustrative sequence. Verify both a real scheduled heartbeat and an alert-destination test before relying on monitoring.

A valid workflow file does not prove the scheduled job ran.

Check the workflow’s default branch, enabled state, runner availability, secrets, and recent run history. A previous green run does not establish that the next scheduled run happened.

GitHub documents delays under load and automatic disabling after 60 days without repository activity for scheduled workflows in public repositories. Check the provider’s current scheduling rules before setting your expectation.

GitHub Actions schedule failure modes:

  • A required secret expired or lost access
  • A runner is unavailable or a workload step failed
  • The workflow or Actions is disabled
  • The scheduled trigger was removed or changed

Setup

Use a reviewed patch, or install the heartbeat manually

In Integrations, connect a selected repository, discover workflows, and choose Review and protect for a supported schedule. After creating the monitor, prepare its installation patch. The manual example below is a separate option: use the PINGCRON_URL Actions secret and replace ./sync.sh with your workload.

The manual example reports success only and a manual dispatch also sends a receipt. The generated installation patch is different: it reports success or failure only on scheduled runs and preserves the workload result if reporting fails. Generated patches currently support one ordinary, non-matrix Ubuntu job; unsupported structures need manual installation. Copying a patch or saving a secret does not establish a successful run.

Real-world examples

Scheduled job with a success heartbeat

# Save as .github/workflows/daily-sync.yml on your default branch.
# Replace ./sync.sh with your workload; it must exit nonzero on failure.
# Add the monitor's success URL as the repository Actions secret PINGCRON_URL.
name: Daily sync
on:
  schedule:
    - cron: '17 2 * * *'
  workflow_dispatch:
permissions:
  contents: read
jobs:
  sync:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4
      - name: Run workload
        run: ./sync.sh
      - name: Report successful completion
        if: success()
        env:
          PINGCRON_URL: ${{ secrets.PINGCRON_URL }}
        run: |
          test -n "$PINGCRON_URL"
          curl --max-time 10 -fsS "$PINGCRON_URL"

What GitHub Actions schedules should you monitor?

Anything you set up with on: schedule that has to keep running.

Nightly test suites

Cron-triggered CI runs against main or production branches.

Database backup workflows

Scheduled pg_dump → S3 jobs running on Actions runners.

Reporting workflows

Daily metrics fetches, internal dashboards, weekly digests.

Dependency scanners

Dependabot-style scans, security audits, SBOM generation.

Deploy / sync jobs

Hourly content syncs, doc rebuilds, mirror pushes.

Stale issue / PR bots

Workflows that close inactive issues — silent failure breaks repo hygiene.

Cross-repo triggers

Scheduled workflow_dispatch calls into other repositories.

External API pulls

Periodic fetches from third-party APIs into repo state.

How it works

Connect only the repositories you choose. Read-only access is enough for discovery, patch preparation, and coverage checks.

01

Discover and review

Inspect scheduled workflows from the default branch. Review the schedule, timezone, and grace before creating a monitor.

02

Save the secret and apply the patch

Copy the monitor-specific secret name and value into GitHub, save it, and review the generated source before committing. PingCron does not write to your repository.

03

Verify a scheduled run and alert

Wait for a real scheduled run. Refresh PingCron to verify the first successful heartbeat, then send an alert-destination test and confirm it arrived.

04

Enable coverage checks

Opt in for each repository in Integrations. Review unlinked workflows, changed schedules, missing supported reporting, lost access, and the last successful scan. Observations target an hourly interval and can be delayed.

Alerts where you'll actually see them.

Save alert destinations for the owning account. Email, Slack, and Discord are included on every plan; custom webhooks require Pro or above.

Email

HTML alerts with monitor details and direct links.

Slack

Post to any Slack channel via incoming webhook.

Discord

Native Discord webhook integration.

Custom webhooks

POST alerts to any endpoint with full payload.

FAQ

No. Connect the repository, discover workflows, review a supported schedule, and create the monitor. Then install its heartbeat and verify a successful run and alert destination.
Yes. Choose grace to accommodate the delays your workload can tolerate. A schedule prediction is not evidence that GitHub executed the workflow.
Report success only after all required workload jobs succeed. Use a final dependent job with explicit dependencies, or separate monitors for independent workloads. Do not let one successful branch hide another failed job.
The generated patch sends heartbeats only on scheduled runs, so a manual dispatch will not activate that monitor. The separate manual example on this page also reports on workflow_dispatch. In either case, a manual run cannot establish that automatic scheduling works.
Opt-in repository scans compare scheduled workflows with saved monitor expectations and supported reporting steps. They can flag unlinked workflows, changed or removed schedules, missing managed instrumentation, and lost access. Unknown custom instrumentation requires manual review. Incomplete scans cannot prove a source was removed; check the last successful scan time.
No. Source observations and heartbeat receipts are separate evidence. PingCron cannot read your saved GitHub secret, establish the correctness of your workload, or identify which GitHub execution sent a receipt. Inspect the run in GitHub as well as the receipt in PingCron.
No. PingCron uses read-only access to selected repositories. It prepares a patch for your review when the workflow structure is supported. You save the secret and apply the change yourself. No pull request is created automatically.

From configuration to a verified first run

In Integrations, install the GitHub App for selected repositories, authorize your GitHub account, and confirm the repository connection. Discover workflows, review a supported schedule, and create a monitor. Store its heartbeat URL as a repository secret, then add a success step after the workload succeeds. Connecting the repository alone does not edit or run your workflow.

Check a GitHub Actions cron schedule →
  • Keep the scheduled workflow on the default branch. Check that Actions and the workflow are enabled.
  • Allow for scheduler delays when choosing grace. GitHub schedules can be delayed or dropped under load; an off-hour minute can reduce contention.
  • For workflows with several jobs, report success only after every required workload job has succeeded. Do not use an unconditional always() success step.

GitHub Actions schedule not running? Find where it stopped.

  1. No scheduled run appears: check the workflow file on the default branch and its enabled state. Public repositories can have schedules disabled after 60 days without activity. Under heavy load, scheduled runs can be delayed or dropped.
  2. A run exists but the job is waiting: inspect runner availability, approvals, and concurrency. A waiting job has not completed your work.
  3. The job started and failed: open the first failed workload step. Check its exit status, required secrets, and destination access before investigating heartbeat delivery.
  4. The workload passed but no receipt arrived: inspect the heartbeat step, confirm the PINGCRON_URL secret is set, and check network access. Never paste the private URL into a public issue.

The downloadable example runs at 02:17 UTC because it sets no timezone. Review the configured timezone if you add one. A manual run can test the workload and receipt; verify a later scheduled run separately.

Download the scheduled workflow example

Replace ./sync.sh and add your own Actions secret before using it. This single-job example sends success only after the workload passes. It cannot prove output correctness or guarantee scheduler dispatch.

Before relying on alerts

  1. Review the monitor’s schedule, timezone, and grace period against the deployed job.
  2. Save your alert destination in Settings, send a labeled test, and confirm that you received it.
  3. Run the actual workload through its scheduler and confirm its first successful heartbeat in PingCron. Copying the URL does not install monitoring.

A successful receipt records what the job reported; it does not prove the output is correct. Detection and delivery timing depend on the schedule, grace period, and alert provider.

Read the official scheduler documentation

Related monitoring guides

Don't let GitHub disable your scheduled workflow without telling you.

Review the schedule, install the heartbeat, and verify the first run. Five monitors are free.

Monitor a scheduled workflow

5 monitors free · No credit card · Verify your first check-in