Heartbeat Monitoring

Monitor your cron jobs, scheduled tasks, and background processes with heartbeat pings.

Heartbeat monitoring ensures that your cron jobs, scheduled tasks, and background processes are running as expected. Instead of checking if your services are up, heartbeats wait for your jobs to "ping" them when they run, start, or complete.

Heartbeats are perfect for monitoring cron jobs, data backups, batch processing, scheduled reports, and any recurring background tasks.

How Heartbeats Work

1

You create a heartbeat

Define a cron schedule (e.g., "daily at 2 AM") and a grace period.

2

Upcron.io generates unique URLs

You get dedicated URLs for success, start, and failure pings.

3

Your script calls the appropriate URL

When your job starts, succeeds, or fails.

4

If no ping arrives within the grace period

An incident is created and you're alerted.

Creating Your First Heartbeat

In your dashboard, go to Heartbeats and click "Create Heartbeat". Fill in:

  • Heartbeat Name — Descriptive name (e.g., "Daily Database Backup")
  • Project — Select the project this heartbeat belongs to
  • Cron Schedule — When your job is expected to run (e.g., 0 2 * * *)
  • Grace Period — How long to wait before alerting (60–86400 seconds)

Cron Schedules

Heartbeats use standard cron expression format: minute hour day month weekday

* * * * *        # Every minute
30 * * * *       # Every hour at :30
30 2 * * *       # Daily at 2:30 AM
0 0 * * 0        # Weekly on Sunday at midnight
0 3 1 * *        # Monthly on the 1st at 3 AM
0 0 1 1 *        # Yearly on January 1st

Fields

Field Range
Minute0–59
Hour0–23
Day1–31
Month1–12
Weekday0–7 (0 and 7 = Sunday)

Special Characters

  • * — Any value (wildcard)
  • , — Multiple values (e.g., 1,15)
  • - — Range (e.g., 1-5 for Mon–Fri)
  • / — Step values (e.g., */5 for every 5 units)

Grace Periods

The grace period determines how long Upcron.io waits after the expected ping time before creating an incident.

1–5 min

Short

For critical jobs that must run on time.

5–60 min

Medium

For jobs with variable runtime.

1–24 hrs

Long

For jobs with unpredictable schedules.

Heartbeat URLs

Each heartbeat provides three unique URLs:

Success URL (Primary)

Call when your job completes successfully.

https://ping.upcron.io/heartbeat/{uuid}

Start URL

Call when your job begins (recommended for long-running tasks).

https://ping.upcron.io/heartbeat/{uuid}/start

Fail URL

Call when your job encounters an error.

https://ping.upcron.io/heartbeat/{uuid}/fail

Implementation Examples

Bash

#!/bin/bash

# Start ping (optional)
curl -m 10 --retry 5 https://ping.upcron.io/heartbeat/YOUR-UUID/start

# Your actual job
if backup_database.sh; then
    curl -m 10 --retry 5 https://ping.upcron.io/heartbeat/YOUR-UUID
else
    curl -m 10 --retry 5 https://ping.upcron.io/heartbeat/YOUR-UUID/fail
fi

Python

import requests, sys

HEARTBEAT_URL = "https://ping.upcron.io/heartbeat/YOUR-UUID"

try:
    requests.get(f"{HEARTBEAT_URL}/start", timeout=10)
    result = run_backup_job()

    if result.success:
        requests.get(HEARTBEAT_URL, timeout=10)
    else:
        requests.get(f"{HEARTBEAT_URL}/fail", timeout=10)
except Exception:
    requests.get(f"{HEARTBEAT_URL}/fail", timeout=10)
    sys.exit(1)

Node.js

const HEARTBEAT_URL = 'https://ping.upcron.io/heartbeat/YOUR-UUID';

async function runJob() {
    try {
        await fetch(`${HEARTBEAT_URL}/start`);
        const result = await performBackup();
        await fetch(result.success ? HEARTBEAT_URL : `${HEARTBEAT_URL}/fail`);
    } catch (error) {
        await fetch(`${HEARTBEAT_URL}/fail`);
        process.exit(1);
    }
}

runJob();

PHP

<?php

$url = "https://ping.upcron.io/heartbeat/YOUR-UUID";
$ctx = stream_context_create(['http' => ['timeout' => 10]]);

try {
    file_get_contents("$url/start", false, $ctx);
    $result = performBackup();
    file_get_contents($result['success'] ? $url : "$url/fail", false, $ctx);
} catch (Exception $e) {
    file_get_contents("$url/fail", false, $ctx);
    exit(1);
}

Best Practices

Always Handle Failures

#!/bin/bash
set -e
trap 'curl https://ping.upcron.io/heartbeat/YOUR-UUID/fail' ERR

perform_backup.sh
generate_report.py

curl https://ping.upcron.io/heartbeat/YOUR-UUID

Use Descriptive Names

Choose clear names: "Daily Customer Database Backup", "Hourly Log Processing Job" — not "Backup Job" or "Script 1".

Troubleshooting

Heartbeat shows as failed but job is running
  • Check if your script is actually calling the ping URLs
  • Verify network connectivity from your server to ping.upcron.io
  • Increase the grace period to accommodate longer job runtimes
  • Check if your cron schedule matches the actual job execution times
Getting alerts for jobs that haven't failed
  • Grace period may be too short for the job's normal runtime
  • Network issues preventing ping requests from reaching Upcron.io
  • Script is calling the wrong heartbeat URL
Ping requests timing out
  • Add timeout and retry logic to your ping requests
  • Use curl with --max-time 10 --retry 3
  • Check firewall settings on your server
  • Verify DNS resolution for ping.upcron.io