Back to blog
3 min read
Uptime monitoringEngineering

How to monitor cron jobs and background workers

HTTP uptime checks will not notice a nightly job that never ran. Heartbeats — or the lack of them — catch the quiet failures that never return a 500.

NK

Nabin Khair

Founder

Uptime monitoring is good at one shape of failure: something that is supposed to answer HTTP stops answering. Cron jobs and workers often fail the other way. They simply never run. No 500. No timeout. No deploy. Just a quiet morning where yesterday's invoices were never generated.

The failure mode URL checks miss

Your API is up. Your dashboard loads. The worker that should have finished at 01:00 did not. Customers notice at 09:00. Your uptime graph is a perfect green ribbon.

That is not a reason to throw away HTTP monitors. It is a reason to stop pretending they cover batch work.

Heartbeats in plain language

Give the job a small extra step: when it finishes successfully, it hits a URL you control (or a provider's "heartbeat" endpoint). Your monitoring side expects that ping on a schedule. If the ping does not arrive in time, that is the incident.

You are not checking "is the server up." You are checking "did the work happen."

Pattern:

  1. Cron starts.
  2. Work runs.
  3. On success, POST or GET the heartbeat.
  4. If the monitor has not seen a beat by expected_time + grace, page someone.

Put the heartbeat at the end, not the start. A job that pings and then dies mid-run will look fine until you learn the hard way.

Grace periods matter

A job scheduled for 01:00 that finishes at 01:04 is not an outage. Clock skew, queue delay, and daylight saving will all create false pages if your grace is zero. Start with something like "expected every 24 hours, alert if more than 25 hours since last beat," then tighten once you know the real runtime.

What to do if you do not have heartbeats yet

Some stacks only have HTTP monitors today. Imperfect options:

  • A tiny authenticated endpoint the job updates (last_success_at), and a separate check that fails when that timestamp is too old.
  • A metrics-based alert if you already run Prometheus or similar.
  • A manual checklist (worst option, but better than nothing for one critical job while you build the real thing).

Do not "monitor" the cron by curling a public page the job is supposed to change. That invents clever failures and misses silent ones.

Tallwatch today is built around HTTP(S) consensus checks for sites and APIs. Heartbeats for cron are something teams ask for once the quiet failures show up, and they are on the roadmap rather than something already shipped. Until then, use a heartbeat-capable tool for the jobs that matter, and keep multi-region HTTP checks on the paths customers hit with a browser.

The rule is the same either way: alert on the absence of expected work, not only on the presence of an error page.

Keep reading

More from the Tallwatch blog

More on monitoring, alerting, and status pages.