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
You create a heartbeat
Define a cron schedule (e.g., "daily at 2 AM") and a grace period.
Upcron.io generates unique URLs
You get dedicated URLs for success, start, and failure pings.
Your script calls the appropriate URL
When your job starts, succeeds, or fails.
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 |
|---|---|
| Minute | 0–59 |
| Hour | 0–23 |
| Day | 1–31 |
| Month | 1–12 |
| Weekday | 0–7 (0 and 7 = Sunday) |
Special Characters
*— Any value (wildcard),— Multiple values (e.g.,1,15)-— Range (e.g.,1-5for Mon–Fri)/— Step values (e.g.,*/5for 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