Cron / heartbeat checks
A cron check (also called a heartbeat or deadman’s switch) is the inverse of an HTTP check. Instead of SiteQwality calling your service, your service calls SiteQwality at the end of each successful run. SiteQwality alerts when the expected ping doesn’t arrive on time.
The pattern is simple:
# At the end of your nightly backup scriptcurl -X POST https://ping.siteqwality.com/<account-id>/<cron-job-id>If the ping doesn’t arrive within check_interval_seconds of the previous one, the check flips to failure and notifications fire.
When to use cron checks
Section titled “When to use cron checks”- Backups, ETL jobs, batch jobs. You want to know when they don’t complete — not just when the host is up.
- Cleanup tasks (purge old data, rotate logs, compact tables) where silence is the failure mode.
- External cron services (cron-job.org, EventBridge, GitHub Actions schedules) that don’t have built-in failure alerting.
When NOT to use them
Section titled “When NOT to use them”- Don’t use cron checks for “is my service running?” That’s an HTTP check job.
- Don’t use them for “is the queue draining?” That’s a metric — emit one and alert on it via a metrics-backed dashboard.
How it works
Section titled “How it works”- You create a cron check in SiteQwality with a
check_interval_seconds— say,86400for a daily job. SiteQwality returns acron_job_id. - Your job pings
https://ping.siteqwality.com/<account-id>/<cron-job-id>at the end of every successful run. - SiteQwality records each ping with a timestamp, source IP, and headers.
- A scheduler runs every minute checking every cron job. If
now - last_received_at > check_interval_seconds + grace_period, the check flips to failure and notifications fire. - The next successful ping flips status back to healthy.
A grace period is automatically applied so a slightly-delayed job (running 24h 5m instead of exactly 24h) doesn’t immediately page. Today the grace period is fixed at one check interval — see grace period notes.
Anatomy
Section titled “Anatomy”| Field | Default | Description |
|---|---|---|
friendly_name | optional | Display name. |
check_interval_seconds | required | Expected interval between pings, in seconds. Validated against AWS Scheduler rate expressions. |
group_notification_ids | [] | Notification groups to fire on state change. Cap of 10. |
state | active | active or paused. Paused checks don’t alert. |
tags | [] | For grouping and matching against maintenance windows. |
What the ping endpoint records
Section titled “What the ping endpoint records”Every ping captures:
- A unique
idfor the receipt. created_at— server-side timestamp.receiving_address— IP fromX-Forwarded-For.receiving_headers— entire headers map (useful for debugging which job pinged).
These are queryable via GET /cron/job/{cron_job_id}/recent.
Pricing
Section titled “Pricing”Cron checks are included on every plan. There’s a soft monthly cap on total pings per account on the free tier — see your Settings → Billing → Usage page.