What actually happened, why "it's scheduled" doesn't mean "it's running," and how to catch it.
Most people find out a scheduled job stopped running when something downstream breaks days later — a report nobody generated, a backup that doesn't exist, a sync that silently drifted. Here's a concrete example of exactly how that happens, from a real incident, not a hypothetical.
LogonType: Interactive, meaning it silently refuses to launch if the screen happens to be locked at the scheduled time. Task Scheduler's own status showed nothing wrong — the task just never started, and Windows doesn't surface that as a visible failure anywhere you'd naturally look.
That's the pattern worth internalizing: "the schedule exists" and "the job ran" are two different facts, and most tooling only shows you the first one. A cron entry, a Windows Task, a CI scheduled pipeline — all of them can have a valid, correctly-configured trigger and still not execute, for reasons that never show up as an "error" anywhere.
The general pattern is called a dead man's switch: instead of watching for a job to fail, you watch for it to stop checking in. The job itself pings something at the end of a successful run; if that ping doesn't arrive on schedule, you get alerted — the absence of a signal is the signal.
Heartbeat Monitor — a self-hosted dead man's switch that runs entirely in your own Google account (Sheets + Apps Script). One curl call at the end of any job checks it in; if it goes silent past its expected interval, you get exactly one email, and one more when it recovers. No subscription, no third-party service, $15 once.
See it in the shop →If something is supposed to run on a schedule and you'd actually be upset to find out three days late that it silently stopped, it needs a check-in mechanism — not just a trigger. "It's scheduled" is not the same claim as "it ran," and the gap between those two is exactly where this kind of incident lives.