Skip to content

Docs

Set up a heartbeat monitor for a cron job

A heartbeat monitor waits for your job to report in. Here is how to create one and add the call to the most common kinds of scheduled job.

Updated 25 October 2026 · By the Upcertain team

Create the monitor

  1. Choose New monitor, then Heartbeat (cron job) monitoring.
  2. Set how often the job runs: from every 30 seconds to every 30 days.
  3. Set a grace period for jobs whose run time varies, up to one day. The default is 60 seconds.
  4. Pick the alert channels and save. Copy the heartbeat URL shown on the monitor.

The URL looks like https://upcertain.com/api/heartbeat/<token>. It accepts GET, POST and HEAD, and answers with JSON containing "ok": true when the call is recorded. The examples below use <token>; paste your own URL.

cron

*/15 * * * * /opt/jobs/sync.sh && curl -fsS -m 10 --retry 3 -o /dev/null https://upcertain.com/api/heartbeat/<token>

&& sends the heartbeat only when the job succeeds. -m 10 gives up after 10 seconds and --retry 3 rides out a brief network failure.

Node.js

async function nightlyReport() {
  await buildReport();
  // Report in only after the work is done.
  await fetch("https://upcertain.com/api/heartbeat/<token>", { signal: AbortSignal.timeout(10_000) });
}

Python

import urllib.request

def main():
    run_backup()
    urllib.request.urlopen("https://upcertain.com/api/heartbeat/<token>", timeout=10)

PHP and Laravel

// Laravel scheduler: ping after a successful run
$schedule->command('reports:send')
    ->daily()
    ->thenPing('https://upcertain.com/api/heartbeat/<token>');
<?php
run_import();
file_get_contents('https://upcertain.com/api/heartbeat/<token>');

thenPing pings after the task runs, whatever the outcome. Use pingOnSuccess instead to ping only when the task succeeds.

GitHub Actions

on:
  schedule:
    - cron: "0 * * * *"
jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ./scripts/sync.sh
      - name: Report to Upcertain
        if: success()
        run: curl -fsS -m 10 --retry 3 "${{ secrets.UPCERTAIN_HEARTBEAT_URL }}"

GitHub may start scheduled workflows late at busy times. Give the monitor a grace period of 15 to 30 minutes for hourly workflows.

Pick the period and grace

  • Period: how often the job is meant to run. A job every 15 minutes gets a 15-minute period.
  • Grace: the longest normal delay plus the longest normal run time. A backup that starts at 02:00 and takes up to 40 minutes needs about 45 minutes of grace.
  • Too little grace means alerts on slow nights; too much means you hear late. Start generous and tighten it after a week.

Limits

Calls from one address may burst to 30 and then one a second; beyond that the endpoint answers 429. Calls for the same monitor within 5 seconds share one answer. Keep the URL private: anyone who has it can report in for the job. If it leaks, create a new heartbeat monitor and delete the old one.