Docs/Cron heartbeat checks

Cron heartbeat checks

Cron checks invert the normal monitor flow: instead of Status Harbor reaching out to your service, your job pings Status Harbor when it finishes. If a ping doesn't arrive when expected, an incident opens.

Use this for: nightly backups, ETL jobs, queue workers, anything that runs on a schedule and isn't reachable from the public internet.

Available on Pro and above. See Plans & limits.

Setup

  1. Crons → New cron in the dashboard. Pick a name, the expected period (how often the job runs) and a grace (how late a ping is allowed before the cron is marked down).
  2. Status Harbor returns a unique ping URL.
  3. Have your job hit the URL on success. GET or POST, both work.
# At the end of your job:
curl -fsS -H "Authorization: Bearer $STATUSHARBOR_TOKEN" \
  https://api.statusharbor.io/api/crons/<cron-id>

The token is an API token with the account scope. Mint one under Settings → API Tokens.

Period and grace

FieldNotes
period_secondsExpected interval between pings. Minimum 60s.
grace_secondsExtra time after the deadline before firing MISSED. Default 300s.

A cron is marked down if now > last_ping_at + period + grace. The scheduler ticks every 30s and applies a 15s dampening window before notifying — pings that arrive within 15s of the deadline silently resolve the implicit miss without paging you.

Don't put your job on the cliff edge

A common pitfall: setting your job's interval equal to period_seconds. A single delayed ping — network blip, GC pause, NTP slew — pushes the gap past period + grace and fires a MISSED alert that recovers seconds later when the next ping lands. We've seen this in the wild with a 60s job on a 60s period; bumping the job interval to 61s stopped the flapping.

Two ways to avoid it:

  1. Run your job slightly faster than period_seconds. A 60s period should be pinged every 50–55s. Each successful cycle pushes the server's deadline forward relative to your job schedule, so the buffer grows monotonically.
  2. Set grace_seconds larger than your worst-case ping delay. If the host occasionally pauses for 30–60s under load, set grace to 60–120s.

States

StateMeaning
pendingJust created, never pinged. No alerts fire yet.
upReceiving pings on schedule.
downMissed expected ping beyond grace. Incident is open.

A ping in any state moves the cron back to up and resolves any ongoing incident.

Notifications

Cron events route through the same channels as monitor events:

  • cron.missed — fired when a cron transitions to down
  • cron.recovered — fired when a missed cron pings again

Recovery messages can be toggled per destination — see Notifications.

Authentication

Tokens are optional but recommended. Without a token, anyone who guesses or leaks the cron ID can ping it. Bind a token at create time and require Authorization: Bearer <token> on every ping — Status Harbor rejects pings with the wrong token.

Limits

  • Plan-gated: Free has zero crons; Pro has a per-plan cap on max_cron_checks. See Plans & limits.
  • Period minimum is 60s — for sub-minute heartbeats, use a regular HTTP monitor against a /healthz endpoint instead.