Tallwatch
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

How to monitor cron jobs and background workers

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 ships heartbeat monitors for this exact case: give the job a check-in URL, set the expected interval and grace period, and Tallwatch pages when the beat is late. Keep multi-region HTTP checks on the paths customers hit with a browser — heartbeats cover the quiet work those checks cannot see.

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

Related

Keep reading

False alerts and status pages.

How to migrate off a free uptime tool without a lost weekend

How to migrate off a free uptime tool without a lost weekend

Leaving a free checker does not require a hero migration. Run both in parallel, match URLs, and cut over when the new pager has earned trust.

NKNabin Khair
Website slow vs website down — how to tell which problem you have

Website slow vs website down — how to tell which problem you have

Latency and downtime feel the same from a frustrated browser. They are different incidents with different fixes — and different paging rules.

NKNabin Khair
What to do in the first two weeks after you turn monitoring on

What to do in the first two weeks after you turn monitoring on

The first fortnight of real monitoring is noisy on purpose. Here is how to tune it into something you trust — before the team learns to mute everything.

NKNabin Khair