Help & guidesHeartbeat (cron monitoring) › Add to cron job (bash, Python, Node)

Add to cron job (bash, Python, Node)

4 min read · Heartbeat (cron monitoring)

Goal: Add a Heartbeat URL to an existing cron job or script so that ePulz.io receives an "I'm alive" ping after every successful run.

How it works

You call the Heartbeat URL after the task completes successfully. If the script fails, the URL is not called, ePulz.io notices the missing ping and sends you an alert.

Bash / shell cron

Add a curl call to the end of the cron line, joined with the && operator (it runs only if the previous command succeeds):

# /etc/crontab or crontab -e
0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 \
  https://epulz.io/heartbeat/Qs78OPNIIsCF_-Vj > /dev/null

What the curl flags mean:

  • -f = fail on an error response (curl returns an error)
  • -s = silent (no progress output)
  • -S = but still show errors (combined with -s)
  • -m 10 = 10 second time limit
  • > /dev/null = keeps the response from flooding the cron log

Python

For Python scripts, add the call via the requests library or the standard urllib:

import os
import requests

HEARTBEAT_URL = os.environ.get("HEARTBEAT_URL")

def sync_data():
    # ... your logic ...
    pass

try:
    sync_data()
    # The heartbeat is sent only if sync_data() did not fail
    if HEARTBEAT_URL:
        requests.get(HEARTBEAT_URL, timeout=10)
except Exception as e:
    # The heartbeat is not sent - ePulz.io will alert you
    print(f"Sync failed: {e}")
    raise

Without an external library, using only the standard one:

import urllib.request

# After the task completes successfully
urllib.request.urlopen("https://epulz.io/heartbeat/Qs78OPNIIsCF_-Vj", timeout=10)

Node.js

const HEARTBEAT_URL = process.env.HEARTBEAT_URL;

async function nightlyJob() {
  await processInvoices();
  // Heartbeat only after successful completion
  await fetch(HEARTBEAT_URL, { signal: AbortSignal.timeout(10000) });
}

nightlyJob().catch(err => {
  console.error(err);
  process.exit(1);  // The heartbeat is not sent, ePulz.io will alert you
});

Docker / systemd timer

When using a systemd timer, add an ExecStartPost line to the .service file:

# /etc/systemd/system/db-backup.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
ExecStartPost=/usr/bin/curl -fsS -m 10 https://epulz.io/heartbeat/Qs78OPNIIsCF_-Vj

ExecStartPost runs only if ExecStart finished successfully.

PHP / Laravel scheduler

// app/Console/Kernel.php
$schedule->command('backup:run')
    ->daily()
    ->thenPing('https://epulz.io/heartbeat/Qs78OPNIIsCF_-Vj');

Laravel has a built-in thenPing() method for exactly this purpose.

Test - simulate a single run

Before adding it to cron, test the URL manually:

$ curl -fsS https://epulz.io/heartbeat/Qs78OPNIIsCF_-Vj
OK

After a successful call, in the ePulz.io overview you will see the monitor status change from Waiting to OK.

Was this guide helpful?