FourSight
    LoginStart free
    Start free
    Reliability & Infrastructure

    Heartbeat Monitoring for Cron Jobs & Scheduled Tasks

    Ensure your cron jobs, background workers, and scheduled tasks run on time — get alerted the moment a job goes silent.

    11 min readGuide

    Why Traditional Monitoring Can't Watch Cron Jobs

    HTTP monitors poll your servers from the outside, but cron jobs, queue workers, and scheduled tasks run inside your infrastructure with no public endpoint. If a nightly billing reconciliation silently stops running, an HTTP check will never notice. Heartbeat monitoring flips the model: your job pings FourSight when it completes, and FourSight alerts you when the ping doesn't arrive on time.

    💡 According to incident post-mortems, over 40% of silent SaaS outages originate from background jobs that stopped running without anyone noticing for hours — or days.

    A Dead-Man's Switch for Your Infrastructure

    The mental model that makes heartbeat monitoring click is the dead-man's switch: the safety mechanism on a train that requires the driver to keep applying pressure — the moment the pressure stops, the brakes engage automatically. Heartbeat monitoring applies the same inversion to your jobs. Instead of asking 'can I reach the server?' (which says nothing about whether last night's backup ran), the system demands continuous proof of life: your job must actively report success, on schedule, forever. Silence is treated as failure. This inversion is what catches the failure modes ordinary monitoring can't: the crontab line deleted in a bad deploy, the server that was decommissioned while its jobs quietly moved nowhere, the scheduler daemon that stopped after a reboot, the job that runs but exits early before doing its work. In every one of those cases nothing is 'down' — there's simply an absence where work should be. A dead-man's switch is the only monitor that hears absence.

    How Heartbeat Monitoring Works

    When you create a heartbeat monitor in FourSight you receive a unique ping URL. Your job sends a simple HTTP request to that URL every time it completes successfully. FourSight tracks the expected interval and a configurable grace period. If a ping doesn't arrive before the deadline, FourSight opens an incident and notifies your team through your configured escalation policy.

    Fixed-Interval Mode

    Set an expected interval (e.g. every 5 minutes, every hour) and a grace window. This is ideal for jobs that run on simple repeating schedules like queue consumers, health-check scripts, or data-sync workers.

    Cron-Expression Mode

    Provide a standard 5-field cron expression (e.g. '30 2 * * *' for 2:30 AM daily). FourSight calculates the next expected run time dynamically, making it perfect for jobs with complex schedules like 'every weekday at 9 AM' or 'first Sunday of the month'.

    Grace Period & Miss Threshold

    The grace period absorbs normal jitter — a job that's 20 seconds late on a 5-minute schedule shouldn't wake anyone up. The miss threshold lets you require multiple consecutive missed pings before alerting, reducing noise from transient issues.

    Setting Up Your First Heartbeat Monitor

    In the FourSight dashboard, create a new monitor and select the Heartbeat type. Choose your schedule mode, set your interval or cron expression, and configure a sensible grace period. FourSight generates a unique ping URL you'll add to the end of your job.

    💡 The && operator matters: the ping only fires if the backup script exits 0. A failing job produces silence, and silence is what triggers the alert. Heartbeat monitors are included in FourSight's Growth plan ($40/mo) and above, alongside the other 7 check types.
    # At the end of your cron job script:
    curl -fsS --retry 3 https://ping.foursight.cloud/hb/<YOUR_TOKEN>
    
    # Example crontab entry — daily DB backup at 3 AM
    0 3 * * * /opt/scripts/backup-db.sh && curl -fsS --retry 3 https://ping.foursight.cloud/hb/<YOUR_TOKEN>

    Copy-Paste: PowerShell & Windows Task Scheduler

    Windows scheduled tasks fail even more silently than cron — Task Scheduler will happily report 'The operation completed successfully' about launching a script that then crashed. Put the ping at the end of the script itself, inside your error handling, so it only fires when the work actually finished.

    # end of your scheduled .ps1 script — ping only on success
    try {
        # ... your script logic ...
    
        Invoke-RestMethod -Uri "https://ping.foursight.cloud/hb/<YOUR_TOKEN>" `
            -Method Get -TimeoutSec 10 | Out-Null
    } catch {
        Write-Error "Job failed: $_"
        exit 1   # no ping fires -> FourSight alerts on the missed heartbeat
    }

    Monitoring a Commercial SaaS?

    FourSight's free plan includes 10 commercial-safe monitors with multi-region validation — free forever, no card.

    Start Monitoring Free

    Copy-Paste: GitHub Actions Scheduled Workflows

    GitHub Actions cron workflows have a notorious silent-failure mode: scheduled workflows are automatically disabled after 60 days of repository inactivity, and schedules can be delayed or skipped during high-load periods. GitHub emails you about some failures — but never about a workflow that simply stopped being scheduled. A heartbeat ping as the final step catches both.

    💡 Store the ping URL token as a repository secret rather than committing it — anyone with the URL can fake a healthy heartbeat.
    name: nightly-job
    on:
      schedule:
        - cron: "0 3 * * *"   # 03:00 UTC daily
    
    jobs:
      run:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - name: Do the actual work
            run: ./scripts/nightly-job.sh
          # Runs only if every previous step succeeded
          - name: Report heartbeat to FourSight
            run: curl -fsS --retry 3 "https://ping.foursight.cloud/hb/${{ secrets.FOURSIGHT_HEARTBEAT_TOKEN }}"

    Copy-Paste: node-cron and In-Process Schedulers

    In-process schedulers like node-cron, node-schedule, or APScheduler add an extra failure layer: the schedule dies whenever the host process does. A crashed Node service takes every scheduled task with it, and nothing external knows those jobs existed. The heartbeat covers both the job logic and the process hosting it.

    import cron from "node-cron";
    
    // Every hour at :05 — sync exchange rates
    cron.schedule("5 * * * *", async () => {
      try {
        await syncExchangeRates();
    
        // Ping only after the work succeeded
        await fetch("https://ping.foursight.cloud/hb/<YOUR_TOKEN>", {
          signal: AbortSignal.timeout(10_000),
        });
      } catch (err) {
        console.error("sync failed:", err);
        // no ping -> missed heartbeat -> alert
      }
    });

    How Do You Tune the Grace Period?

    The grace period is the slack between a job's expected check-in and the moment FourSight declares it missing. Too tight and normal runtime variance pages you for nothing; too loose and a genuinely dead job goes unreported for hours. Two rules cover most cases. For frequent jobs (every 1–15 minutes), set the grace period to roughly 20–50% of the interval — enough to absorb scheduler jitter and a slow network call. For infrequent jobs (hourly to daily), size the grace period from the job's runtime instead: worst-observed runtime plus 50%, because a nightly warehouse refresh that takes 12 minutes on a normal Monday may take 45 at month-end. If you're pinging at the end of the job (recommended), remember the deadline is schedule time + runtime + grace — budget for all three.

    💡 Start stricter than feels comfortable, then loosen based on real misses. A grace period you had to widen twice is calibrated; one you guessed generously on day one is a blind spot.
    Job schedule Typical runtime Suggested grace period Reasoning
    Every 5 min (queue worker) Seconds 1–2 min Absorb jitter; still alert within minutes
    Hourly sync 1–5 min 10–15 min Runtime variance + one slow run
    Nightly backup, 3 AM 10–45 min 60 min Worst-case runtime + 50%
    Weekly report, Mon 6 AM ~10 min 2–3 hours Infrequent job — favor certainty over speed
    Month-end billing run Varies widely Worst case + 50% Consider a 2-miss threshold too

    Common Use Cases

    Heartbeat monitoring is useful anywhere a process should run on a predictable schedule.

    Database Backups

    Append a ping to your pg_dump or mysqldump script. If tonight's backup doesn't complete, you'll know by morning — not during the next disaster recovery drill.

    Queue Workers & Consumers

    Have your worker ping FourSight on each processing cycle. If the worker crashes or the queue stalls, the missed heartbeat triggers an alert before messages pile up.

    Billing & Invoice Generation

    Scheduled billing runs are revenue-critical. A missed invoice cycle can cascade into payment failures and churn. Heartbeat monitoring catches the silence.

    Data Sync & ETL

    Nightly data imports, warehouse refreshes, and third-party API syncs all benefit from heartbeat checks that confirm successful completion.

    Best Practices

    Place the ping call after your job's success criteria, not at the start — a ping that fires before the work happens monitors your scheduler, not your job. Use --retry flags on curl (or explicit timeouts in code) so a transient network blip doesn't register as a dead job. Treat ping URLs as secrets: anyone holding one can fake a healthy heartbeat, so keep tokens in environment variables or secret stores, not in committed code. For long jobs, consider two monitors — one pinged at start, one at completion — to distinguish 'never started' from 'started but hung.' And pair every revenue-critical heartbeat with an escalation policy so a missed 3 AM backup pages the on-call engineer instead of sitting unread in a Slack channel.

    Frequently Asked Questions

    Protect Your SaaS Revenue

    Start monitoring in under 60 seconds.