Heartbeat monitoring for cron jobs and workers

Your jobs check in when they finish. When one goes quiet, Zvono opens an incident and pages whoever is on call.

Alerts on silence, not just errors

Scheduled jobs rarely fail loudly. They stop running, and nothing notices until the data is missing. A heartbeat flips the model: the job reports in, and a missing report is the alarm.

  1. 1

    Create a monitor

    Name it, pick how often the job runs, and choose how much lateness to tolerate. Each monitor gets its own ping URL.

  2. 2

    Ping when the work is done

    Your job sends a signed request to the ping URL after it succeeds. One line with curl, or one call with the Node or Python SDK.

  3. 3

    Silence pages someone

    If no ping arrives within the interval plus grace period, the monitor goes down and an alert follows your escalation policy.

Upapi.zvono.io
24h7d30d
Uptime timeline
UpDown
00:0006:0012:0018:00Now
Uptime
99.96%
Incidents
1
Last ping
12 sec ago

Failures a health check never sees

Every one of these ends the same way: no ping. That is all a heartbeat needs to notice.

  • Jobs that never start: the host was replaced, the crontab is gone, or the scheduler skipped the run
  • Jobs that hang on a lock or a network call with no timeout
  • Jobs that fail because a secret rotated or an environment variable is missing
  • Workers and queue consumers that crash and never restart
  • Errors that go nowhere because output is piped to /dev/null

Tuned to page on real failures

Every monitor has the settings that separate a job that stopped from a job that ran a little late.

Interval

1 to 60 minutes

How often the job should check in. Set it to the job's schedule.

Grace period

Up to 30 minutes

Extra time before a late ping counts as missed, to absorb scheduler jitter and slow runs.

Failure threshold

1 to 20 misses

How many consecutive misses before an incident opens, so one dropped ping doesn't wake anyone.

Explicit failures

status: "down"

Jobs that catch an error can report it with a reason and get an alert immediately, instead of waiting for the timeout.

Flap detection

On by default

A monitor that keeps flipping between up and down collapses into one flapping state and one alert.

Cooldown window

Up to 24 hours

Suppress new incidents for a while after one resolves, for jobs you know will be noisy.

Not sure what to pick? Our guide to intervals, thresholds and grace periods walks through it.

One call at the end of the job

Zero-dependency SDKs for TypeScript and Python sign each ping for you. Anything that can make an HTTPS request works too.

TypeScript (@zvono/sdk)
import { Zvono } from "@zvono/sdk";

const zvono = new Zvono({ secret: process.env.ZVONO_SECRET! });

try {
  const processed = await syncOrders();
  await zvono.ping("hourly-order-sync", {
    status: "up",
    metadata: { processed },
  });
} catch (err) {
  await zvono.ping("hourly-order-sync", {
    status: "down",
    reason: "sync-failed",
  });
  throw err;
}
Python (zvono)
import os
from zvono import Zvono

zvono = Zvono(secret=os.environ["ZVONO_SECRET"])

try:
    rows = export_report()
    zvono.ping("hourly-report", status="up", metadata={"rows": rows})
except Exception:
    zvono.ping("hourly-report", status="down", reason="export-failed")
    raise

Setting up crontab, Kubernetes CronJobs, GitHub Actions or Vercel cron? See how to monitor cron jobs, or the ping API reference.

The alert reaches a person

A missed heartbeat is an alert like any other in Zvono. It goes to whoever is on call, follows your escalation policy from Slack to SMS and phone calls, groups repeat failures into one incident, and can resolve itself once the job reports healthy again. Monitoring, on-call schedules and PTO live in one tool for one flat team price.

Frequently asked questions

What is heartbeat monitoring?

Heartbeat monitoring alerts on silence instead of errors. Your job sends a ping each time it finishes, and if a ping does not arrive on time, the monitor assumes something is wrong. It is the standard way to catch scheduled jobs that stop running, sometimes called a dead man's switch.

How is this different from uptime monitoring?

Uptime monitoring probes a URL from the outside. Heartbeat monitoring is push-based: your code calls Zvono, and Zvono never makes requests into your infrastructure. That makes it a fit for cron jobs, workers and anything without a public endpoint. Zvono does not do outbound HTTP checks.

How often can a job run?

Monitors accept intervals from 1 to 60 minutes, with grace periods up to 30 minutes. Jobs that run less often than hourly, such as nightly backups, are not supported yet.

How are pings authenticated?

Each ping is signed with an HMAC-SHA256 signature of the request body using your team's secret, so nobody else can mark your jobs healthy. The TypeScript and Python SDKs sign requests for you.

What does it cost?

Heartbeat monitoring is included on the Basic plan at $16 per month and the Pro plan at $39 per month, priced per team rather than per user. The free Developer plan covers schedules and PTO but does not include monitors or alerting.

Know when a job stops

Heartbeat monitoring is included on Basic and Pro, priced per team, not per user.

Free Developer plan · Upgrade when you need alerting