Cron job monitoring
for missed runs.
Heartbeat monitoring for backups, reports and every scheduled task. Each job pings its own URL when it finishes, and your team is alerted when a run is missed.
Included on every plan, Free too. No credit card required.
Trusted by teams that put uptime first.
Read customer storiesSix ways a cron job fails silently. Each one misses its ping.
Cron job monitoring turns silence into an alert. Each job pings Hyperping when it runs, and a ping that doesn’t arrive on schedule is treated as downtime. It catches what logs can’t: a job that never started writes no error at all.
- 0 2 * * * · rebooted at 01:58no ping by 02:30 · alert
The job that never started
A reboot, a container that didn’t come back, a crontab lost in a redeploy. Nothing runs, so nothing logs an error. The missing ping is the only trace, and it’s enough.
How healthchecks work - backup.sh · exit 1&& curl skipped · alert
The job that crashed
Chain the ping after the command with &&, and a run that exits with an error never pings. Hyperping alerts you as soon as the grace period runs out.
Ping only on success - /start 02:00 · no end pingdeadline passed · alert
The job that hangs
A lock that never releases, a query stuck on a table. Ping /start when the job begins and the URL when it ends: every run’s duration is logged, and a run that never ends misses its deadline.
Measure run time - 0 2 * * * · read as UTCcron mode · Europe/Paris
The schedule in the wrong timezone
Give the healthcheck the job’s own cron expression and timezone. The deadline follows daylight saving time with it, so a job that runs at 2:00 in Paris is expected at 2:00 in Paris.
Cron expression generator - worker · last ping 47 min agoevery 15 min · alert
The worker that quietly stopped
A queue consumer, a sync loop, a Laravel or Rails scheduler. Anything that runs in a loop can ping on each pass, and simple mode alerts when the pings stop coming.
Simple mode - GitHub Actions · schedule offno ping · alert
The scheduled workflow nobody saw switch off
GitHub disables scheduled workflows in public repositories after 60 days without activity, and a CI runner can stay queued. A ping as the workflow’s last step tells you when it stopped running.
GitHub Actions example
One URL per job. One line in your crontab.
No agent and no SDK. A healthcheck is a URL your job calls, and Hyperping watches the clock.
- 1
Create a healthcheck
Name it after the job and give it the job’s schedule: an interval, or the same cron expression and timezone. Add a grace period a little longer than a normal run.
- 2
Ping its URL when the job finishes
A HEAD, GET or POST request from anything that speaks HTTP. In a crontab, chain it with
&&so only a successful run pings. Add/startat the beginning to log how long each run takes. - 3
Get alerted when a run is missed
No ping by the expected time plus the grace period, and the healthcheck goes down: an incident opens and your channels are alerted within seconds. The next ping closes it and sends a recovery.
# Back up at 2:00 every night, ping Hyperping only if it succeeds
0 2 * * * /usr/local/bin/backup.sh && curl -fsS --retry 3 https://hc.hyperping.io/tok_8f3kq2Lm9xV4#!/bin/sh
set -e
# The run starts: its duration is measured from here
curl -fsS --retry 3 https://hc.hyperping.io/tok_8f3kq2Lm9xV4/start
pg_dump "$DATABASE_URL" | gzip > /backups/db-$(date +%F).sql.gz
# The run ends: Hyperping logs the duration and the next deadline
curl -fsS --retry 3 https://hc.hyperping.io/tok_8f3kq2Lm9xV4await sendInvoices();
// Ping at the end of the job
await fetch("https://hc.hyperping.io/tok_8f3kq2Lm9xV4");import requests
build_report()
# Ping at the end of the job
requests.get("https://hc.hyperping.io/tok_8f3kq2Lm9xV4", timeout=10)use Illuminate\Support\Facades\Schedule;
// Laravel pings /start before the run, and the URL only if it succeeds
Schedule::command("backup:run")
->dailyAt("02:00")
->timezone("Europe/Paris")
->pingBefore("https://hc.hyperping.io/tok_8f3kq2Lm9xV4/start")
->pingOnSuccess("https://hc.hyperping.io/tok_8f3kq2Lm9xV4");func main() {
if err := syncInventory(); err != nil {
// No ping: Hyperping alerts once the grace period runs out
log.Fatal(err)
}
// Ping at the end of the job
client := http.Client{Timeout: 10 * time.Second}
if _, err := client.Get("https://hc.hyperping.io/tok_8f3kq2Lm9xV4"); err != nil {
log.Printf("ping failed: %v", err)
}
}on:
schedule:
- cron: "0 2 * * *"
jobs:
backup:
runs-on: ubuntu-latest
steps:
- run: ./backup.sh
- run: curl -fsS --retry 3 https://hc.hyperping.io/tok_8f3kq2Lm9xV4apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-report
spec:
schedule: "0 6 * * *"
timeZone: "Europe/Paris"
jobTemplate:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: report
image: ghcr.io/acme/report:latest
command: ["/bin/sh", "-c"]
args: ["./report.sh && curl -fsS https://hc.hyperping.io/tok_8f3kq2Lm9xV4"]# Started every night by backup.timer (OnCalendar=*-*-* 02:00:00)
[Unit]
Description=Nightly database backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# Runs only if ExecStart exited with success
ExecStartPost=/usr/bin/curl -fsS --retry 3 https://hc.hyperping.io/tok_8f3kq2Lm9xV4# Run the job's container, ping only if it exits with code 0
0 2 * * * docker run --rm --env-file /etc/backup.env ghcr.io/acme/backup:latest && curl -fsS --retry 3 https://hc.hyperping.io/tok_8f3kq2Lm9xV4
# Same with a Compose service
0 3 * * * cd /srv/app && docker compose run --rm report && curl -fsS --retry 3 https://hc.hyperping.io/tok_8f3kq2Lm9xV4# Windows Task Scheduler action: powershell.exe -File C:\jobs\export-orders.ps1
& C:\jobs\export-orders.exe
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
# Ping at the end of the job
Invoke-RestMethod -Uri "https://hc.hyperping.io/tok_8f3kq2Lm9xV4" -TimeoutSec 10Simple or cron. In the job’s own timezone.
A healthcheck knows when the next run is due, so it alerts on the run that didn’t happen, not hours later when someone notices.
- 1
Simple mode, for loops and workers
Expect a ping every so many minutes, hours or days, from 1 minute up. The clock restarts at each ping, which suits workers and syncs that run in a loop.
- 2
Cron mode, for scheduled jobs
Paste the job’s five-field expression and pick its timezone. Each run is expected when cron would start it, weekends and daylight saving changes included. Unsure of the syntax? Use the cron expression generator.
- 3
A grace period for slow runs
How long to wait after the expected time before alerting, 10 minutes unless you change it. A backup that usually takes 4 minutes can get 30, so a slow night doesn’t page anyone.
- Mode
- Simple
- Every
- 15 minutes
- Grace period
- 5 minutes
- Last ping
- Oct 6, 09:14:58
- Down if no ping by
- Oct 6, 09:34:58
- Oct 6, 09:29:58 · next ping expected
- Oct 6, 09:34:58 · end of grace period
In simple mode the clock restarts at every ping: 15 minutes until the next one, plus 5 minutes of grace. A worker that stops pinging is reported 20 minutes after its last pass.
- Mode
- Cron
- Expression
- 0 2 * * *
- Timezone
- Europe/Paris
- Grace period
- 30 minutes
- Down if no ping by
- Oct 7, 02:30 CEST
- Wed, Oct 7 · 02:00 CEST
- Thu, Oct 8 · 02:00 CEST
- Fri, Oct 9 · 02:00 CEST
In cron mode the deadline follows the expression, not the last ping. A backup that pings at 02:04 tonight is still expected at 02:00 tomorrow, with 30 minutes of grace.
- Mode
- Cron
- Expression
- 0 9 * * 1-5
- Timezone
- America/New_York
- Grace period
- 15 minutes
- Down if no ping by
- Nov 2, 09:15 EST
- Mon, Nov 2 · 09:00 EST
- Tue, Nov 3 · 09:00 EST
- Wed, Nov 4 · 09:00 EST
Friday’s report pinged at 09:02. Nothing is expected over the weekend, so nothing alerts, and the clock change on November 1 doesn’t move Monday’s run: the timezone does the arithmetic.
- Mode
- Cron
- Expression
- 0 0 1 * *
- Timezone
- UTC
- Grace period
- 2 hours
- Down if no ping by
- Nov 1, 02:00 UTC
- Sun, Nov 1 · 00:00 UTC
- Tue, Dec 1 · 00:00 UTC
- Fri, Jan 1 · 00:00 UTC
A monthly job is the one nobody notices for weeks. A two-hour grace period leaves room for a slow run and still raises the alert long before anyone asks where the invoices are.
A missed run is an incident. Your team hears about it first.
Healthchecks are checked every few seconds against their deadline, so the alert goes out as soon as the grace period ends, and the incident sits in the same list as your other monitors.
- Uppinged on schedule
The last run pinged in time. The next deadline is set from the schedule: the next ping in simple mode, the next cron run in cron mode.
- Grace perioddue, no ping yet
The run is due and hasn’t pinged yet. The healthcheck stays up and nothing is sent until the grace period runs out, so a job that runs a few minutes long stays quiet.
- Downmissed its scheduled ping
The grace period ran out. An incident opens, every channel is alerted at once, and it stays down until the job pings again: one alert per missed run, not one per minute.
- Recoveredback on schedule
The next ping resolves the incident and sends a recovery on the same channels. PagerDuty and Opsgenie alerts close on their own.
Where your team works.All at once, the moment it’s late.
Email and SMS reach every member of the project, and Slack, Discord and Telegram the channels you connected. Send it to PagerDuty or Opsgenie to page whoever is on call there.
Slack
PagerDuty
Opsgenie
Discord
Telegram
- SMS
Next to your uptime checks. On the same status page.
Healthchecks live in the same account as your monitors, incidents and status pages, so a missed import and a slow API are one dashboard apart.
- Oct 06 02:48:21 · OK · 4m 09slast 20 pings kept
Every run, logged
Each ping records its time, IP address, method and user agent, and the duration of the run when it started with /start. A 24-hour chart shows the runs hour by hour.
Ping history - Nightly database backup · 99.93%uptime bars · status page
On your status page
Add a healthcheck to a status page next to your websites and APIs. Customers see the import, the sync or the report as one more service, up or down, with its uptime.
Status pages - 30 days · uptime · CSVweekly report email
In your reports
Healthcheck uptime is computed from its outages, over 30 days by default, exported to CSV and included in the weekly report next to your monitors.
Reporting
Healthchecks as code. From the API, Terraform or your AI agent.
- 1
Create them from the API
POST name, a cron expression and its timezone, or period_value and period_type, plus the grace period. The response carries the ping URL to hand to your job.
- 2
Or declare them in Terraform
The hyperping_healthcheck resource keeps every job’s healthcheck next to the infrastructure that runs it, and outputs its ping URL as a sensitive value.
- 3
Ask your AI agent if the backup ran
The MCP server lists your healthchecks with their state, last ping and next deadline, so Claude, Cursor or another agent can answer “did last night’s jobs run?”.
curl -X POST https://api.hyperping.io/v2/healthchecks \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Nightly database backup",
"cron": "0 2 * * *",
"timezone": "Europe/Paris",
"grace_period_value": 30,
"grace_period_type": "minutes"
}'resource "hyperping_healthcheck" "nightly_backup" {
name = "Nightly database backup"
cron = "0 2 * * *"
timezone = "Europe/Paris"
grace_period_value = 30
grace_period_type = "minutes"
}
output "backup_ping_url" {
value = hyperping_healthcheck.nightly_backup.ping_url
sensitive = true
}{
"uuid": "hc_Kq3vX9mPzL2wR8tY5nB7cD4f",
"name": "Nightly database backup",
"state": "up",
"last_ping_at": "2026-10-06T00:04:12.000Z",
"next_ping_due_at": "2026-10-07T00:00:00.000Z",
"down_if_no_ping_by": "2026-10-07T00:30:00.000Z",
"schedule": "cron '0 2 * * *' (Europe/Paris)",
"grace": "30 minutes"
}A guide for your scheduler. Where the ping goes, and how it fails.
Every scheduler hides failures in its own way. Each guide is a tested setup: what goes wrong, how to see it with the scheduler’s own tools, and the healthcheck that catches the missed run.
Servers and platforms
- systemd timersPersistent=true, timezones, a ping only on success.
- Windows Task SchedulerA failed task that reports success.
- Kubernetes CronJobsMissed schedules and pods stuck in Pending.
- GitHub Actions schedulesDelayed runs and the 60-day auto-disable.
- Vercel cron jobsNo retries, redirects and timeouts.
- Cloudflare Workers Cron TriggerswaitUntil, and 1 means Sunday.
Frameworks and queues
- Laravel schedulerpingOnSuccess or thenPing, and schedule:run.
- Rails scheduled jobsSolid Queue, GoodJob and whenever.
- Node.js cron jobsnode-cron, BullMQ and Agenda.
- Celery beatA beat that publishes with no worker.
- Sidekiq cron jobsRetries that hide the failure.
- pg_cronJobs that stop after a restart or a failover.
Jobs that can’t fail quietly
Compare
A service that should always answer? That’s uptime monitoring.
Healthchecks wait for your jobs to call. Uptime monitors call your websites and APIs as often as every 30 seconds, from up to 17 regions. Most teams run both, on the same plan.
What 50 or 500 jobs cost. Free plans included.
If cron jobs are all you monitor, Healthchecks.io costs less. Hyperping is worth it when the same plan also watches your websites and APIs and runs your status page: healthchecks count toward the plan’s monitors, nothing is billed per job, and Essentials includes 3 seats.
| Monthly priceUSD, monthly billing, one user | HyperpingHealthchecks count as monitors | Healthchecks.ioCron monitoring, open source | CronitorBilled per monitor and per user |
|---|---|---|---|
| Free plan | 20 jobsShared with uptime monitors | 20 jobsHobbyist | 5 jobsHacker, 1 user |
| 50 jobs | $29Essentials, $24 billed yearly | $20Business, up to 100 jobs | $10550 × $2, plus $5 per user |
| 500 jobs | $299Business, $249 billed yearly | $80Business Plus, up to 1,000 jobs | $1,005500 × $2, plus $5 per user |
| Also in the price | Uptime monitors, status pages, on-call for monitorsWithin the same monitor count | Cron monitoring onlyOpen source, free to self-host | Uptime checks, status pageBilled per monitor too |
Prices checked on October 8, 2026 on each vendor’s pricing page. Every tool and its limits, side by side: the best cron job monitoring tools.
What teams say about Hyperping.

@hyperping is really amazing

Hyperping’s reputation in our company is that it’s more reactive than Datadog. We usually get notifications from Hyperping before Datadog.

We picked Hyperping to bring a high quality incidents and status reporting dashboard to our users.

We have the real-time alerts from Hyperping telling us if the app is down. These are sometimes arriving even before AWS notices or notifies us.

We couldn’t imagine running our SaaS business without Hyperping now.

Hyperping nails all aspects: from smooth setup to peace of mind and attentive customer service.
Questions about cron job monitoring.
What is cron job monitoring?
Cron job monitoring checks that scheduled tasks actually run. Each job pings a unique URL when it finishes, and the monitoring service alerts you when a ping doesn’t arrive on schedule. It catches what logs can’t: a job that never started writes no error at all. Hyperping calls these monitors healthchecks.
How do I monitor a cron job?
Create a healthcheck with the job’s schedule, as an interval or as its cron expression and timezone, and a grace period. Copy its ping URL and add a request to the end of the job, such as && curl -fsS followed by the URL in your crontab. If the ping doesn’t arrive by the expected time plus the grace period, Hyperping alerts you.
What is heartbeat monitoring, or a dead man’s switch?
The same idea under other names. Instead of a monitor checking your service, your job sends a signal, the heartbeat, on every run, and the alert fires when the signal stops. It suits anything with no URL to check: cron jobs, backups, queue workers, ETL pipelines and scheduled CI workflows.
Coming from Opsgenie heartbeats?
Opsgenie shuts down on April 5, 2027, heartbeats included. Each heartbeat becomes a healthcheck with the same interval, and its ping URL replaces the Opsgenie ping in your job. One difference: a missed run alerts every channel at once instead of paging your on-call schedule, so route healthcheck alerts to PagerDuty if someone must be woken up. The Opsgenie migration guide has a script that recreates them all.
How do I know if a cron job failed?
Ping only when the job succeeds: in a shell, chain the request after the command with &&, and in code, call the URL after the work is done. A job that crashes, exits with an error or never starts then sends nothing, and Hyperping alerts you once the grace period passes. Hyperping doesn’t store the job’s exit code or output, so keep your logs for the why.
What is a grace period in cron monitoring?
It’s how long Hyperping waits after the expected run time before alerting. A backup scheduled at 2:00 with a 30-minute grace period can ping until 2:30. Set it a little above the job’s usual duration so slow runs don’t page anyone. It starts at 1 minute and defaults to 10 minutes in the dashboard.
Does Hyperping understand cron expressions and timezones?
Yes. In cron mode, give a healthcheck the job’s five-field expression, such as 0 9 * * 1-5, and its timezone, such as America/New_York. Hyperping computes each expected run from them, so weekends without runs don’t alert and daylight saving changes are handled. Build or check an expression with the cron expression generator.
Can I see how long my cron jobs take?
Yes. Ping the URL with /start appended when the job begins, and the plain URL when it ends. The healthcheck’s history shows each run’s duration, along with the time, IP address, method and user agent of every ping. A run that starts but never finishes misses its deadline and alerts like a missed run.
Can I monitor Kubernetes CronJobs, GitHub Actions or Windows scheduled tasks?
Yes. Anything that can make an HTTP request can ping a healthcheck: curl or wget in a crontab, a systemd timer or a Kubernetes CronJob, a step at the end of a GitHub Actions or GitLab CI workflow, Invoke-WebRequest in a Windows scheduled task, or a request from your code in a Laravel, Rails, Django or Node.js scheduler.
What’s the difference between cron job monitoring and uptime monitoring?
Uptime monitoring checks a service from the outside: Hyperping calls your website or API as often as every 30 seconds and alerts when it stops answering. Cron job monitoring works the other way around: your job calls Hyperping, and silence is the failure. Most teams need both, and Hyperping runs them side by side. See uptime monitoring.
Is cron job monitoring free?
Healthchecks are included on every plan, the Free plan too. Each healthcheck counts as one of the plan’s monitors: 20 on Free, 50 on Essentials, 250 on Pro and 1,000 on Business, shared with your uptime checks. See pricing.
How does Hyperping compare with Cronitor or Healthchecks.io?
Cronitor goes deeper into job analytics and Healthchecks.io is open source and free to self-host. Hyperping keeps cron monitoring next to uptime checks, status pages and incidents in one account. See Hyperping vs. Cronitor and Hyperping vs. Healthchecks.io, or every tool side by side in the best cron job monitoring tools.


