Monitor cron jobs and background workers with heartbeats

Create a heartbeat monitor and ping it from crontab, a systemd timer, GitHub Actions or a Kubernetes CronJob. Supports jobs that run every 15 seconds to 1 hour.

Updated By the Uptime Tracker team
  1. Create a Heartbeat monitorGo to Monitors, choose "New monitor" and select the Heartbeat check type.
  2. Set the expected intervalEnter how often the job runs in "Expected every (seconds)", from 15 to 3600 seconds.
  3. Set a grace periodEnter a Grace period (seconds), from 0 to 3600, to allow for late runs.
  4. Copy the heartbeat URLChoose "Create monitor", then copy the heartbeat URL. It is shown only once.
  5. Call the URL after each successful runAdd a GET or POST request to the URL at the end of your job, for example with curl -fsS.

A heartbeat monitor alerts you when a scheduled job stops running. Instead of us checking your server, your job calls a secret URL after each successful run. If no call arrives within the expected interval plus the grace period, an incident opens and alerts go out. Heartbeats are available on every plan: 5 on Free, 10 on Starter, 50 on Team.

Supported schedules

The expected interval can be 15 seconds to 1 hour (3,600 seconds). The grace period can be 0 to 60 minutes. Daily or weekly jobs are not supported yet, because the longest interval is 1 hour. Each heartbeat accepts up to 10 signals per minute, and only success pings exist: there are no separate start or failure signals, so call the URL only when the job succeeded.

Copy the URL when it is shown

After you choose Create monitor, the page shows Your heartbeat URL. It is shown only once. Use Copy URL or Copy curl command and store it with your job's configuration, ideally as a secret. Anyone who has it can report the job as healthy. If you lose it, delete the monitor and create a new one. The URL looks like https://uptimetracker.live/api/v1/heartbeats/YOUR_TOKEN.

crontab

Chain the ping with && so it only runs if the job succeeds:

*/15 * * * * /usr/local/bin/backup.sh && curl -fsS -m 10 --retry 3 https://uptimetracker.live/api/v1/heartbeats/YOUR_TOKEN > /dev/null

systemd timer

For a Type=oneshot service, ExecStartPost runs only after ExecStart succeeds:

# /etc/systemd/system/sync.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/sync.sh
ExecStartPost=/usr/bin/curl -fsS -m 10 --retry 3 https://uptimetracker.live/api/v1/heartbeats/YOUR_TOKEN

# /etc/systemd/system/sync.timer
[Timer]
OnCalendar=*:0/15
Persistent=true

[Install]
WantedBy=timers.target

GitHub Actions

Store the URL as a repository secret named HEARTBEAT_URL. Scheduled workflows can start late, so use a generous grace period.

on:
  schedule:
    - cron: '*/30 * * * *'
jobs:
  nightly-sync:
    runs-on: ubuntu-latest
    steps:
      - run: ./scripts/sync.sh
      - name: Report heartbeat
        if: success()
        run: curl -fsS -m 10 --retry 3 "${{ secrets.HEARTBEAT_URL }}"

Kubernetes CronJob

Keep the URL in a Secret and make sure the image includes curl:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: report-export
spec:
  schedule: "*/10 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: Never
          containers:
            - name: job
              image: registry.example.com/report-export:latest
              command: ["/bin/sh", "-c", "/app/export && curl -fsS -m 10 --retry 3 \"$HEARTBEAT_URL\""]
              env:
                - name: HEARTBEAT_URL
                  valueFrom:
                    secretKeyRef:
                      name: uptime-heartbeats
                      key: report-export

Choosing the grace period

Set the grace period to cover normal variation in start time and run time. The default is 5 minutes. A job that runs every 15 minutes and sometimes takes 4 minutes is safe with a 5 to 10 minute grace.

FAQ

Frequently asked questions

Can I monitor a daily or weekly cron job?

Not yet. The expected interval can be at most 1 hour, so heartbeats suit jobs that run every 15 seconds to every hour.

Should I use GET or POST?

Either works. A plain curl request (GET) is the simplest option.

Can I see the heartbeat URL again later?

No. It is shown only once when you create the monitor. If you lose it, delete the monitor and create a new one; editing does not change the URL.

Can I report a failed run?

There is no separate failure signal. Only call the URL when the job succeeds; a missing ping is what triggers the alert.

Uptime Tracker

Start monitoring in under five minutes

Start on the free plan — commercial use allowed. No credit card, no password, just your email address.

  • Free forever plan
  • No credit card
  • Cancel anytime