Your cron job’s been dead since Tuesday.
No alert. No email. Nothing.

Most monitoring tools tell you something pinged. We tell you when it didn’t — within 60 seconds. One HTTP call. Python SDK and Bash CLI today; Node, Go, Ruby when they’re actually finished, not when marketing says so.

No credit cardFree forever for 5 monitorsSetup in 60 seconds

backup.py
✓ ping received· nightly-backup · 1.4s · exit 0

The problem

Cron jobs fail silently. That's the problem.

A failed exit code can be ignored. A job that never ran has nothing to ignore. Most monitoring tools watch for errors — yours can't watch for absence.

Failed

The job ran. It told you it broke.

Exit code 1, an exception, a timeout — your script reported failure on the way out. Send a FAILURE check-in with whatever JSON metadata you want (exit code, duration, error string) and CronBeacon stores it alongside the run.

monitornightly-backup
outcomeFAILURE
metadata: {
  "exit_code": 137,
  "error": "OOM killed",
  "duration_ms": 4200
}
Missing

The job didn't run. There's nothing to report.

The container died. The cron daemon was disabled. The deploy clobbered the schedule. There's no log line — there's no line. CronBeacon notices the silence within your grace window and pages you anyway.

monitornightly-backup
expected at02:00 UTC
overdue14m · grace exceeded
last seen26h 14m ago

Other tools tell you something's wrong. CronBeacon tells you what went wrong.

Works with your stack

Anything that can hit an HTTPS endpoint can talk to CronBeacon. These are the runtimes we have docs and recipes for.

awsAWSdkrDockerk8sKubernetesghGitHub ActionsvcVercelryRailwayrdrRenderhkHeroku

Three steps. About sixty seconds.

Create a monitor, add one line to your cron, get alerted when something's wrong. The third step is the only one we do for you.

01

Create a monitor

Name it, give it a schedule in cron syntax (or pick a friendly preset), and set a grace window. You get a bearer token to authenticate check-ins.

Name
nightly-backup
Schedule
0 2 * * *
↳ every day at 02:00 UTC
Grace
15 minutes
Token: cb_live_••••••••abc123(shown once)
02

Add one line to your cron

Append a curl to your existing job. POST to the ingestion endpoint with your bearer token; the outcome travels in the JSON body.

# before
0 2 * * * /usr/local/bin/backup.sh

# after — POST a SUCCESS check-in if the job exits 0
0 2 * * * /usr/local/bin/backup.sh && curl -fsS -X POST \
  https://cronbeacon.dev/api/v1/ingestion/check-in \
  -H "Authorization: Bearer $CB_TOKEN" \
  -d '{"outcome":"SUCCESS"}'

# on failure, post FAILURE so we know it ran but broke
|| curl -fsS -X POST \
  https://cronbeacon.dev/api/v1/ingestion/check-in \
  -H "Authorization: Bearer $CB_TOKEN" \
  -d '{"outcome":"FAILURE"}'

Prefer an SDK? Python today, Node + Go + Ruby Q3 2026.

03

Get alerted the moment something's wrong

One channel for missing, one for failed, none for noise. Alerts are merged into incidents — one outage, one ping, one resolution.

CronBeacon2:14 AM
Missing check-in: nightly-backup
Expected at 02:00 UTC · now 14m overdue · grace window 15m exceeded.
Last successful run · 24h 14m ago · exit 0 · 1.4s

The failures every other tool politely ignores.

Detection

Know the difference between silent and broken.

Failed jobs talk. Missing jobs stay silent. CronBeacon listens to both.

Failed check-ins arrive as a FAILURE outcome with whatever JSON metadata your job decides to send. Missing check-ins arrive as the absence of any check-in within your grace window. Same incident view, two completely different signals — and you can route them to two completely different channels.

  • Exit-code-aware failure detection
  • Grace-window-based absence detection
  • Per-channel routing for Failed vs Missing
nightly-backupFailed
exit 137 · 4.2s · "No space left on device"
02:00 UTC
invoice-monthlyMissing
expected 00:00 UTC · 14m overdue · grace 15m exceeded
+14m
data-syncFailed
exit 1 · 38.0s · "connection reset by peer"
14:30 UTC
log-rotateHealthy
exit 0 · 612ms
15:00 UTC

Incidents

One outage, one incident. Not 47 missing pings.

When your server goes down, you get one incident alert, not a flood.

If your every-minute health check goes silent for four hours, that's one incident with 240 missed pings — not 240 alerts. We open an incident on the first miss, keep it open while the silence continues, and close it the moment the next ping lands.

  • Incidents bracket missed pings instead of multiplying them
  • Auto-close on first successful ping after silence
  • One alert per incident, not per ping
Incident #142 · health-check-euResolved
Window
03:21 → 07:08 UTC
Missed pings
227
Ping cadence
03:21 · Incident opened — first missed ping
03:22–07:07 · 226 missed pings merged into incident
07:08 · Incident auto-closed on next successful ping

Alerting

Alerts that respect your time.

Per-monitor grace periods and short delivery delays so a self-recovering blip doesn't wake you up.

Every alert is scheduled with a brief delay before it actually goes out. When the worker is about to send, it re-checks whether the incident is still open. If the next run already succeeded and closed it, the alert is cancelled before it reaches your inbox — and you'll see it cancelled in the timeline.

  • Per-monitor grace periods
  • Auto-cancellation if the job recovers before delivery
  • One alert per incident — no flood when a job is silent for hours
02:17:08Alert openednightly-backup overdue 2m past grace
02:19:12Job succeeded1.4s · exit 0
02:19:13Alert cancelled before deliveryself-recovered within window
Your phone never buzzed. that's the point.

The honest table our competitors won’t publish.

Honest comparison. We listed the things we're worse at too. Updated May 2026.

CronBeaconCronitorHealthchecks.ioDead Man's Snitch
Free tier monitors55201
Paid tier (entry)$19/mo · 50 monitors$10/mo · 5 monitors$5/mo · 20 monitors$5/mo · 3 monitors
Distinguishes Missing vs Failedmissing onlymissing only
Incident-level trackingpartial
Custom JSON metadata per check-in
Open-source SDK
Python · MIT
Node, Go, Ruby — Q3 2026
BSD
API + integrations
Smart alert delaysauto-cancels if job recovers
Typical setup time~60s~2 min~60s~30s
Pulled from each tool's public pricing and docs in May 2026. We will not pretend to be best at everything — Healthchecks.io is the right call if you self-host, and Dead Man's Snitch is faster to set up if all you need is “did this email get sent on Tuesday.” If you're choosing between us and Cronitor, we think the Missing-vs-Failed distinction and incident-level tracking are worth the price delta.

Pricing. No “Contact us” button.

Same product on every tier. Higher tiers buy you more monitors, longer history, and more alert channels.

SAVE 20%
Free
For side projects and solo developers.
$0/mo · forever
Always free
  • 5 monitors
  • Email alerts
  • 7-day check-in history
  • Missing-vs-Failed detection
  • Incident timeline & auto-resolution
  • Job metadata (JSON payload)
Most popular
Pro
For developers running production workloads.
$19/mo
billed monthly · or $180/year
  • 50 monitors
  • Email alerts
  • Slack & webhook alertscoming soon
  • 90-day check-in history
  • Missing-vs-Failed detection
  • Incident timeline & auto-resolution
  • Job metadata (JSON payload)
  • Priority email support
Unlimited
For infrastructure you can't afford to lose.
$49/mo
billed monthly · or $468/year
  • Unlimited monitors
  • Email alerts
  • Slack & webhook alertscoming soon
  • 365-day check-in history
  • Missing-vs-Failed detection
  • Incident timeline & auto-resolution
  • Job metadata (JSON payload)
  • Dedicated support

Every tier includes the core CronBeacon experience: missing detection, failure tracking, incidents, and metadata. Cancel anytime — no email asking why.

Frequently asked.

How is CronBeacon different from Cronitor / Healthchecks.io?
We treat Missing and Failed as separate signals and roll every miss or failure into one incident with a timeline — instead of a stream of identical alerts. Healthchecks.io and Dead Man's Snitch only watch for absence; Cronitor distinguishes them too, but the incident is the central abstraction here.
How does the Missing-vs-Failed distinction actually work?
Send a check-in with `"outcome": "FAILURE"` and we mark that run Failed. If we don't see any check-in for a monitor within its schedule plus grace period, that's Missing. Both open an incident; only the cause differs.
Do I need an SDK or is curl enough?
Curl is enough. POST to the ingestion endpoint with your bearer token and a JSON body containing `"outcome": "SUCCESS"` (or `"FAILURE"`). Language-specific SDKs aren't shipped today — anything that can make an HTTPS request works.
How do alerts get merged into incidents?
The first miss or failure opens the incident. Subsequent missed runs while the incident is open are linked to it — they show in the timeline but don't fire new alerts. The first successful check-in after the incident closes it.
Do you cancel an alert if the job recovers before delivery?
Yes. Alerts are scheduled with a short delay; when they're about to fire, the worker re-checks whether the incident is still open. If the next run already succeeded and closed the incident, the alert is cancelled before it ever reaches your inbox.
What metadata can I attach to a check-in?
Any JSON object via the `metadata` field — duration, record counts, error messages, whatever you want. It's stored in Postgres alongside the check-in for the duration of your plan's history retention (7 days on Free, 90 on Pro, 365 on Unlimited).
Which alert channels are supported?
Email today. Slack and webhook are on the roadmap and shown as "coming soon" on Pro and Unlimited. Quiet hours, PagerDuty, and on-call rotations aren't built yet either — we'd rather ship one channel that works reliably than four that mostly do.
Can I self-host CronBeacon?
Not today, and we haven't put a date on it. If self-hosting is non-negotiable, Healthchecks.io is the right call — they're open source and battle-tested.

Still letting your customers QA your cron jobs? Bold strategy.

First ping takes 60 secondsNo card neededCancel anytime