← Blog
Monitoring 6 min read

Heartbeat Monitoring: How to Know When Your Cron Jobs Fail

Cron jobs fail silently. No error page, no alert, no trace — they just stop running. Heartbeat monitoring catches this by inverting the check: instead of PingBase polling your service, your job pings PingBase. Silence is the alert.


The silent failure problem

Most monitoring tools watch your web-facing services: does your homepage load? Is your API returning 200s? These are outward-facing checks — if something breaks, the tool notices because it can't reach you.

Cron jobs and background tasks are different. They run on your infrastructure, on a schedule, without a public-facing endpoint. When they fail, there's nothing to check. No URL to poll. No HTTP response to inspect. The job just quietly stops doing its job.

Examples of what breaks silently:

In each case, the job ran fine hundreds of times before. There was no deployment, no code change — it just stopped. And nobody found out until a user complained, a payment was missed, or a backup was needed and didn't exist.


How heartbeat monitoring works

Heartbeat monitoring inverts the normal uptime check. Instead of a monitoring service polling your URL, your job calls a URL that the monitoring service gives you.

The flow:

  1. You create a heartbeat monitor in PingBase and set an expected interval (e.g. every 24 hours)
  2. PingBase gives you a unique ping URL
  3. You add a single HTTP request to the end of your job — a GET or POST to that URL
  4. Every time the job runs successfully, it pings PingBase
  5. If PingBase doesn't receive a ping within the expected window, it alerts you

The elegance of this pattern: silence is the failure condition. You don't need to detect what went wrong — you just need to notice that the expected ping didn't arrive. This works regardless of why the job failed: crash, timeout, misconfigured cron, deploy that inadvertently disabled the scheduler, or a dependency outage.


What to monitor with heartbeats

A good rule: any scheduled task where missing a run has consequences is worth a heartbeat monitor. Here's a practical checklist:

High priority — monitor these first

  • Database backups
  • Payment processing / retry jobs
  • SSL certificate auto-renewal
  • Security scans or compliance checks

Medium priority

  • Email digest / notification jobs
  • Data sync and import jobs
  • Search index rebuilds
  • Analytics aggregation jobs

Lower priority (still worth it)

  • Log rotation and cleanup jobs
  • Cache warming jobs
  • Expired session cleanup

Setting up a heartbeat monitor in PingBase

  1. Log in to PingBase and click Add monitor
  2. Select Heartbeat as the monitor type
  3. Give it a name (e.g. "Nightly DB backup") and set the expected interval (e.g. every 24 hours)
  4. Optionally set a grace period — how long after the expected interval PingBase should wait before alerting (useful for jobs with variable run times)
  5. Save — PingBase generates a unique ping URL for this monitor
  6. Add the ping call to the end of your job (see examples below)

The monitor starts in a "waiting" state. After the first successful ping, it becomes active and will alert you if a ping is missed.


Code examples

Shell / cron

# Run backup, then ping on success
/usr/local/bin/backup.sh && curl -fsS https://ping.pingba.se/hb_abc123 > /dev/null

Node.js

async function runNightlyJob() {
  try {
    await doTheWork();
    // Ping on success
    await fetch('https://ping.pingba.se/hb_abc123');
  } catch (err) {
    console.error('Job failed:', err);
    // Don't ping — PingBase will alert after the grace period
  }
}

Python

import requests

def run_backup():
    try:
        do_backup()
        # Ping on success
        requests.get('https://ping.pingba.se/hb_abc123', timeout=5)
    except Exception as e:
        print(f"Backup failed: {e}")
        # Don't ping — PingBase will alert

GitHub Actions

- name: Ping PingBase heartbeat
  if: success()
  run: curl -fsS https://ping.pingba.se/hb_abc123 > /dev/null

The key pattern in all examples: only ping on success. If the job errors, skip the ping — PingBase will notice the silence and alert you after the grace period expires.


FAQ

What's a grace period?

Grace periods give your job extra time before PingBase considers it missed. If you have a job scheduled for midnight that typically finishes by 12:05am but occasionally takes up to 30 minutes, set a 30-minute grace period. PingBase waits until 12:30am before alerting — so you don't get paged for a slow-but-successful run.

What if my job runs multiple times a day?

Set the interval to match the shortest expected gap between runs. If a job runs every 6 hours, set a 6-hour interval. PingBase expects a ping every 6 hours and alerts if it doesn't receive one.

Can I ping from behind a firewall or VPN?

Yes. The ping URL is a simple outbound HTTP GET — as long as your server has outbound internet access (which almost all servers do), it will work. You don't need to open any inbound ports.

What happens if my job runs but the ping fails?

Treat this like a job failure — investigate why your server can't reach the ping URL. In practice, outbound HTTP from a server almost never fails. But if it does, the alert is still useful: something about your environment changed.


Start monitoring your cron jobs for free

Heartbeat monitors are included on all PingBase plans. Set up your first monitor in under 60 seconds — no credit card required.

Add a heartbeat monitor →