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
- 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).
- Status Harbor returns a unique ping URL.
- Have your job hit the URL on success.
GETorPOST, 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
| Field | Notes |
|---|---|
period_seconds | Expected interval between pings. Minimum 60s. |
grace_seconds | Extra 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:
- 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. - Set
grace_secondslarger than your worst-case ping delay. If the host occasionally pauses for 30–60s under load, set grace to 60–120s.
States
| State | Meaning |
|---|---|
pending | Just created, never pinged. No alerts fire yet. |
up | Receiving pings on schedule. |
down | Missed 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 todowncron.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
/healthzendpoint instead.