Heartbeat Monitoring for Cron Jobs and Background Workers
Traditional uptime monitoring works by polling your service — an HTTP request every 30 seconds, a TCP connection to a port, or an ICMP ping. That model breaks down when the thing you need to monitor can't be reached from the outside.
Cron jobs, background workers, queue consumers, nightly backups, and services behind firewalls all share the same problem: there is no endpoint to poll. They run on a schedule or in response to events, and they don't expose a public URL.
Heartbeat monitoring solves this by flipping the direction. Instead of Upwarden checking your service, your service checks in with Upwarden. If it stops checking in, you get alerted.
How Heartbeat Monitoring Works
The concept is simple:
- You create a heartbeat monitor in Upwarden and set an expected interval (for example, every 5 minutes).
- Upwarden gives you a unique push URL.
- Your service sends a GET or POST request to that URL after each successful run.
- If Upwarden doesn't receive a heartbeat within the expected interval plus an optional grace period, the monitor is marked as down and your team gets notified.
No authentication is required on the push URL — the token in the URL itself acts as the credential. This makes integration trivial: a single curl command at the end of a script.
When to Use Heartbeat Monitors
Heartbeat monitoring is the right choice when:
- Cron jobs — nightly backups, data exports, report generation, database cleanup. Add a
curlto the end of the script to confirm it ran. - Background workers — queue consumers, async processors, email senders. Send a heartbeat on each processing cycle.
- Scheduled tasks — anything that runs on a timer (systemd timers, Kubernetes CronJobs, cloud scheduler functions).
- Services behind firewalls — internal microservices, on-premise systems, IoT devices that can make outbound HTTP calls but aren't reachable from the internet.
- Batch pipelines — ETL jobs, data sync processes, ML training runs.
The common thread: these are things that should run on a schedule, and silence means failure.
Setting It Up in Upwarden
Create a new monitor and select Heartbeat as the type. You'll configure:
- Name — something descriptive like "Nightly database backup" or "Invoice queue worker".
- Description — a free-text field (replaces the target URL since there's nothing to poll).
- Expected interval — how often your service should check in. Set this to match your cron schedule or processing cycle.
- Grace period — extra seconds before marking the monitor as down. Useful for jobs that occasionally run a few seconds late.
After creation, Upwarden generates a unique push URL:
https://upwarden.eu/api/v1/heartbeat/<your-token>
Copy this URL and add it to your script or service.
Integration Examples
Cron Job (Bash)
#!/bin/bash
# Nightly backup script
pg_dump mydb > /backups/mydb-$(date +%F).sql
# Report success to Upwarden
curl -fsS --max-time 10 https://upwarden.eu/api/v1/heartbeat/YOUR_TOKEN
The -fsS flags make curl fail silently on HTTP errors and --max-time 10 prevents the heartbeat call from hanging your script.
Kubernetes CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: data-export
spec:
schedule: "0 */6 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: export
image: myapp:latest
command:
- /bin/sh
- -c
- |
python export.py && \
curl -fsS https://upwarden.eu/api/v1/heartbeat/YOUR_TOKEN
restartPolicy: OnFailure
Python Script
import requests
def process_queue():
# ... your processing logic ...
pass
if __name__ == "__main__":
process_queue()
requests.get("https://upwarden.eu/api/v1/heartbeat/YOUR_TOKEN", timeout=10)
Node.js Worker
async function processJobs() {
// ... your worker logic ...
}
await processJobs();
await fetch("https://upwarden.eu/api/v1/heartbeat/YOUR_TOKEN");
How the Grace Period Works
The grace period adds a buffer to the expected interval. If your cron job is scheduled to run every hour, but occasionally takes a few extra minutes, set the grace period to 300 seconds (5 minutes).
The monitor is only marked as down when:
time since last heartbeat > expected interval + grace period
This prevents false alerts from minor timing variations while still catching genuine failures.
Heartbeat vs. HTTP Monitoring
| HTTP Monitoring | Heartbeat Monitoring | |
|---|---|---|
| Direction | Upwarden → your service | Your service → Upwarden |
| Requires public URL | Yes | No |
| Works behind firewalls | No | Yes |
| Works for cron jobs | No | Yes |
| Measures response time | Yes | No |
| Checks HTTP status codes | Yes | No |
Use HTTP monitoring for web-facing services. Use heartbeat monitoring for everything else that runs on a schedule.
Security Considerations
The push URL contains a unique token that acts as authentication. Treat it like a secret:
- Don't commit it to public repositories.
- Store it in environment variables or a secrets manager.
- If a token is compromised, regenerate it from the monitor detail page — the old URL immediately stops working.
Getting Started
If you have cron jobs or background workers that should run on a schedule, create a free Upwarden account and set up your first heartbeat monitor. It takes less than a minute, and you'll know immediately if something stops running.
For more on what to monitor, see our practical monitoring checklist.