Skip to main content

Heartbeat Monitoring

Heartbeat monitoring helps you ensure 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.

What are Heartbeats?

Heartbeats work by providing you with unique URLs that your scripts and scheduled tasks call to signal they’re running correctly. If a heartbeat doesn’t receive a ping within its expected timeframe (based on the cron schedule and grace period), Upcron.io creates an incident and alerts you.
Heartbeats are perfect for monitoring cron jobs, data backups, batch processing, scheduled reports, and any recurring background tasks.

How Heartbeats Work

Unlike uptime monitors that actively check your services, heartbeats are passive monitors that wait for your services to check in:
  1. You create a heartbeat with a cron schedule (e.g., “daily at 2 AM”)
  2. Upcron.io generates unique URLs for your heartbeat
  3. Your script calls the appropriate URL when it starts, succeeds, or fails
  4. If no ping is received within the grace period, an incident is created

Creating Your First Heartbeat

1

Navigate to Heartbeats

In your Upcron.io dashboard, go to the Heartbeats section within your project.
2

Add New Heartbeat

Click “Create Heartbeat” and fill in the required information:
  • 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 * * * for daily at 2 AM)
  • Grace Period: How long to wait after the expected time before alerting (60-86400 seconds)
3

Configure Advanced Settings

Optional configurations:
  • Next Ping At: Manually set when the next ping is expected
  • Description: Additional details about what this heartbeat monitors
4

Save and Get URLs

Click “Create Heartbeat” to save and receive your unique ping URLs.

Understanding Cron Schedules

Heartbeats use cron expression format to define when your jobs are expected to run:
* * * * *

Cron Format Explanation

The cron format uses five fields: minute hour day month weekday
  • Minute: 0-59
  • Hour: 0-23 (24-hour format)
  • Day: 1-31
  • Month: 1-12
  • Weekday: 0-7 (0 and 7 are Sunday)

Understanding Grace Periods

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

Short Grace Period

60-300 seconds (1-5 minutes)For critical jobs that must run on time

Medium Grace Period

300-3600 seconds (5-60 minutes)For jobs that may have variable runtime

Long Grace Period

3600-86400 seconds (1-24 hours)For jobs with unpredictable schedules or long runtimes

Examples

  • Database backup: 30 minutes
  • Email reports: 1 hour
  • Data sync: 15 minutes
  • Log rotation: 2 hours

Heartbeat URLs

Each heartbeat provides three unique URLs for different scenarios:

1. Success URL (Primary)

Call this when your job completes successfully:
https://ping.upcron.io/heartbeat/{uuid}
curl https://ping.upcron.io/heartbeat/9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d

2. Start URL

Call this when your job begins (optional but recommended for long-running tasks):
https://ping.upcron.io/heartbeat/{uuid}/start

3. Fail URL

Call this when your job encounters an error:
https://ping.upcron.io/heartbeat/{uuid}/fail

Implementing Heartbeats in Your Scripts

Basic Implementation

#!/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
    # Success ping
    curl -m 10 --retry 5 https://ping.upcron.io/heartbeat/YOUR-UUID
else
    # Failure ping
    curl -m 10 --retry 5 https://ping.upcron.io/heartbeat/YOUR-UUID/fail
fi

Advanced Implementation with Run IDs

For jobs that may run multiple times or overlapping instances:
#!/bin/bash

RUN_ID=$(date +%s)
HEARTBEAT_URL="https://ping.upcron.io/heartbeat/YOUR-UUID"

# Start with run ID
curl "$HEARTBEAT_URL/start?rid=$RUN_ID"

# Your job here
if perform_task.sh; then
    curl "$HEARTBEAT_URL?rid=$RUN_ID"
else
    curl "$HEARTBEAT_URL/fail?rid=$RUN_ID"
fi

Best Practices

1. Always Handle Failures

Ensure your scripts can ping the fail URL when something goes wrong:
# Use proper error handling
set -e  # Exit on any error

# Trap errors and ping fail URL
trap 'curl https://ping.upcron.io/heartbeat/YOUR-UUID/fail' ERR

# Your job commands here
perform_backup.sh
generate_report.py

# Success ping only reached if no errors
curl https://ping.upcron.io/heartbeat/YOUR-UUID

2. Set Appropriate Grace Periods

Grace Period: 1-5 minutesFor jobs that should complete quickly:
  • Log rotation
  • Simple file operations
  • Quick health checks

3. Use Descriptive Names

Choose clear names that describe what the heartbeat monitors:
 Good names:
- "Daily Customer Database Backup"
- "Hourly Log Processing Job"
- "Weekly Sales Report Generation"
- "Monthly User Data Cleanup"

 Unclear names:
- "Backup Job"
- "Daily Task"
- "Script 1"
- "Cron"

4. Test Your Implementation

Before deploying, test your heartbeat implementation:
1

Test Success Path

Run your script manually and verify it pings the success URL correctly.
2

Test Failure Path

Simulate a failure condition and verify it pings the fail URL.
3

Test Network Issues

Ensure your script handles network timeouts gracefully with retries.
4

Verify Scheduling

Confirm your cron schedule matches when your job actually runs.

Common Use Cases

Database Backups

#!/bin/bash
HEARTBEAT="https://ping.upcron.io/heartbeat/YOUR-UUID"

curl "$HEARTBEAT/start"

if mysqldump -u root -p database_name > backup.sql; then
    curl "$HEARTBEAT"
else
    curl "$HEARTBEAT/fail"
fi

Log Processing

import requests
import logging

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

try:
    requests.get(f"{heartbeat}/start")
    
    # Process logs
    process_application_logs()
    
    requests.get(heartbeat)
except Exception as e:
    logging.error(f"Log processing failed: {e}")
    requests.get(f"{heartbeat}/fail")

Data Synchronization

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

async function syncData() {
    try {
        await fetch(`${heartbeat}/start`);
        
        const result = await synchronizeWithExternalAPI();
        
        if (result.success) {
            await fetch(heartbeat);
        } else {
            await fetch(`${heartbeat}/fail`);
        }
    } catch (error) {
        console.error('Sync failed:', error);
        await fetch(`${heartbeat}/fail`);
    }
}

Troubleshooting

Possible solutions:
  • 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
Common causes:
  • Grace period is too short for the job’s normal runtime
  • Network issues preventing ping requests from reaching Upcron.io
  • Script is calling the wrong heartbeat URL
  • Cron schedule doesn’t match actual job timing
Solutions:
  • Add timeout and retry logic to your ping requests
  • Use curl with --max-time 10 --retry 3 options
  • Check firewall settings on your server
  • Verify DNS resolution for ping.upcron.io
Solutions:
  • Use run IDs to distinguish between job instances
  • Implement proper locking to prevent overlapping executions
  • Adjust grace period to account for potential overlaps
  • Consider using process management tools like systemd

Next Steps