Article

Catching Silent Failures: Monitoring Cron Jobs and Scheduled Tasks

T
TwoPulse Team 5 min read
Catching Silent Failures: Monitoring Cron Jobs and Scheduled Tasks

An API that goes down is loud — users hit errors immediately, and someone notices within minutes. A cron job that stops running is quiet. Nobody's actively waiting on it in real time, there's no user-facing error page, and it can fail for weeks before anyone realizes a report never generated, a cleanup task never ran, or a data sync silently stopped. Silent failures are some of the most damaging incidents precisely because nothing announces them.

Why Scheduled Tasks Fail Differently Than Request-Driven Services

A web service that's down produces an immediate, visible symptom — a failed request. A cron job that's broken produces nothing at all: no error, no user complaint, just an absence. That absence is easy to miss unless something is specifically watching for it. Common failure modes include:

  • The job stops running entirely — a deploy removed the schedule, a server was decommissioned, a config change broke the trigger
  • The job runs but fails partway through — an exception gets swallowed, and it looks like a normal run in the logs
  • The job runs successfully but does nothing useful — a query returns zero rows due to an upstream change, and the task "succeeds" without doing its actual job

None of these produce the kind of loud, immediate signal that a downed API does — which is exactly why they need deliberate monitoring rather than being assumed to work.

The Cost of Not Knowing

The damage from a silently broken scheduled task tends to scale with how long it goes unnoticed. A daily report that fails to generate for one day is a minor annoyance; the same failure running silently for three weeks can mean a month of missing data that's expensive or impossible to reconstruct. The earlier a silent failure is caught, the cheaper it is to fix — which is the core argument for monitoring these tasks at all.

The Core Pattern: Heartbeat Checks

The standard approach to catching silent failures is having the scheduled task itself report in when it completes — commonly called a heartbeat or dead man's switch pattern. The task pings a monitoring endpoint on successful completion; if that ping doesn't arrive within the expected window, that absence itself becomes the alert. This flips the monitoring model: instead of watching for something going wrong, you're watching for an expected signal not arriving, which is exactly the shape of a silent failure.

Setting Realistic Expected Windows

A heartbeat check is only useful if its expected timing matches the job's actual schedule, with reasonable tolerance. A few practical guidelines:

  • Set the expected window slightly wider than the job's normal runtime, so ordinary variance doesn't trigger false alarms
  • For jobs with variable runtime (a batch job whose duration depends on data volume), base the window on worst-case observed runtime, not the average
  • Revisit the window if the underlying job's schedule or typical duration changes — a stale expected-window setting is a common source of both false alarms and missed detections

Distinguish "Didn't Run" From "Ran but Failed"

A heartbeat that never arrives tells you the job didn't complete — but it doesn't tell you whether it never started, crashed partway through, or is still running late. Where possible, having the task report in at both start and successful completion (rather than just completion) gives a clearer picture of which failure mode you're dealing with, which matters when deciding how urgently to respond.

Monitoring Scheduled Tasks With TwoPulse

TwoPulse supports heartbeat-style monitoring for exactly this use case — your cron job or scheduled task pings a unique TwoPulse URL when it completes, and if that ping doesn't arrive within the window you define, it's treated the same as any other downtime event, with alerts routed through your usual email or webhook configuration. Because it's logged alongside your other uptime data, a pattern of a specific job missing its window shows up in the same alert history you already check for everything else, instead of requiring a separate system just for scheduled tasks.

Frequently Asked Questions

What's the difference between heartbeat monitoring and regular uptime monitoring?

Regular uptime monitoring checks whether a service responds when pinged. Heartbeat monitoring flips this — it waits for the monitored task to report in on its own schedule, and alerts when that expected signal doesn't arrive.

How wide should my expected time window be?

Wide enough to absorb normal runtime variance without triggering false alarms, but tight enough that a real failure still gets caught promptly — base it on the job's worst-case observed runtime rather than its average.

Can I monitor a cron job that runs on an irregular schedule?

Yes, as long as you can define a reasonable maximum expected gap between runs — the monitoring just needs an upper bound on "how long is too long since the last successful ping."

What should I do if a heartbeat check fails?

Treat it like any other downtime alert: investigate why the expected ping didn't arrive, whether the job never ran, crashed, or is simply running later than expected, and fix the underlying cause before the next scheduled run.

Is it worth monitoring every scheduled task, even minor ones?

Prioritize tasks where a silent failure would cause real damage — data syncs, billing jobs, cleanup tasks with downstream dependencies. Genuinely low-stakes scheduled tasks may not justify the same monitoring investment.

Have a cron job you're just hoping is still running? Get started with TwoPulse and set up a heartbeat check in minutes — or log in to add one to an existing scheduled task.

---

Related Articles

Continue reading more insights on microservices monitoring

Ready to monitor your microservices?

Start monitoring your services with real-time heartbeat checks, latency monitoring, and automated alerts.

Get Started