GitHub Actions Scheduled Workflows

Monitor GitHub Actions scheduled workflows.

PingCron alerts you when a cron-triggered GitHub Actions workflow stops running, gets disabled by inactivity, or silently fails. One curl step and you'll know within seconds.

5 monitors free · No credit card · Live in under 60 seconds

GitHub Actions silently disables scheduled workflows after 60 days of repository inactivity.

GitHub disables scheduled workflows in repositories that haven't had activity in 60 days. The workflow file still exists. The cron expression still looks correct. The Actions tab shows a green checkmark on the last run. But the workflow simply isn't being invoked anymore — and GitHub does not send you a notification when it happens.

Beyond the 60-day rule, scheduled workflows can also fail in subtle ways. A typo in the cron expression that GitHub silently rounds. A required secret that was rotated and never re-added. A self-hosted runner that's offline. A workflow_dispatch that was meant to also be schedule-triggered but only one trigger was kept after a refactor.

The classic GitHub Actions cron failure pattern: it ran fine last week, you didn't change anything, and now it just doesn't fire. No error. No notification. Just absence.

GitHub Actions schedule failure modes:

  • Repository hit 60 days of inactivity — GitHub disabled the schedule with no email
  • A required secret expired and the workflow now fails on the auth step
  • Self-hosted runner offline — workflow queued indefinitely with no timeout
  • Cron expression was edited and the new schedule is broken or impossible
  • GitHub's scheduled workflow infrastructure had an outage you never noticed
  • Workflow was renamed and the old name's schedule was orphaned

Setup

Add one ping step at the end of your workflow.

If the workflow stops running for any reason, PingCron alerts you. Works for both schedule and workflow_dispatch triggers.

Before

name: Daily Sync
on:
  schedule:
    - cron: '0 2 * * *'

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

After

name: Daily Sync
on:
  schedule:
    - cron: '0 2 * * *'

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./sync.sh
      - name: Ping PingCron
        if: success()
        run: curl -fsS https://api.pingcron.io/ping/abc123

The if: success() condition ensures the ping only fires when every previous step succeeded. If a step fails, the ping never runs and PingCron alerts you after the grace period. To get instant failure alerts, add a separate step with if: failure() that pings /fail.

Real-world examples

With explicit failure ping

      - name: Ping success
        if: success()
        run: curl -fsS https://api.pingcron.io/ping/abc123

      - name: Ping failure
        if: failure()
        run: curl -fsS https://api.pingcron.io/ping/abc123/fail

Start + finish pings (catches hung workflows)

      - name: Ping start
        run: curl -fsS https://api.pingcron.io/ping/abc123/start

      - run: ./sync.sh

      - name: Ping finish
        if: success()
        run: curl -fsS https://api.pingcron.io/ping/abc123

Reusable composite action

# .github/actions/pingcron/action.yml
name: PingCron
inputs:
  monitor_id:
    required: true
  status:
    default: success
runs:
  using: composite
  steps:
    - shell: bash
      run: |
        URL="https://api.pingcron.io/ping/${{ inputs.monitor_id }}"
        if [ "${{ inputs.status }}" = "fail" ]; then URL="$URL/fail"; fi
        curl -fsS "$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

Three steps. About a minute total.

01

Create a GitHub Actions workflow monitor

Set the interval to match your cron expression (hourly, daily, weekly).

02

Add a curl step at the end of your workflow

Use if: success() so the ping only fires when every prior step succeeded.

03

Get alerted on missed runs

Whether GitHub disabled the workflow, the runner is offline, or a step failed — you get notified within seconds of the grace period elapsing.

Alerts where you'll actually see them.

Configure as many channels as you want per monitor.

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

Add a curl step at the end of your workflow with if: success(). The step pings a unique PingCron URL only when every previous step succeeded. If the workflow stops running — disabled by GitHub, runner offline, or a step fails — the ping doesn't arrive and PingCron alerts you.
It's an anti-abuse measure. GitHub auto-disables scheduled workflows in repositories that haven't had activity (commits, issues, PRs) in 60 days to reduce wasted compute on abandoned repos. The catch: GitHub does not send you a notification when it disables your workflow, and the workflow file still looks fine. PingCron catches this within hours of the next missed run.
Pushes, PRs, issues, comments, releases, and a few other interactions. Just running a scheduled workflow does not count. To keep a long-running scheduled workflow alive, you need genuine repo activity or a workaround like a manual workflow_dispatch every couple months.
Yes. The curl step runs wherever the workflow runs. If the self-hosted runner is offline, the workflow never executes, the ping never arrives, and PingCron alerts you. This is one of the main reasons to set up monitoring — self-hosted runner outages are easy to miss.
Use two pings. if: success() pings on success, if: failure() pings /fail. If neither ping arrives, the workflow didn't run at all (disabled, runner offline, schedule broken). If only the failure ping arrives, the workflow ran but a step failed. PingCron's UI shows you which signal you received.
Yes, but the use case is different. For purely manual workflows, PingCron's missed-check-in alert isn't useful — there's no expected schedule. For workflows triggered by both schedule and workflow_dispatch, set the monitor's interval to match the schedule trigger and ignore the manual runs (extra pings just confirm the monitor is healthy).
Yes. 5 monitors free with email, Slack, and Discord alerts. No credit card required. Plenty for monitoring 5 critical scheduled workflows.

Related monitoring guides

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

One curl step in your workflow. Get alerted the moment a scheduled run is missed.

Start monitoring free

5 monitors free · No credit card · Live in under 60 seconds