Get a Quote!

+1-(334) 899-1293

707 Midland Exd St Ashford, Alabama(AL), 36312

Edit Template

How to Verify Your Scheduler Is Actually Running (Heartbeat Checks)

The first symptom of a dead scheduler is never an error message — it’s silence. Nothing crashes loudly, nothing sends an alert, nothing changes on the dashboard in an obviously alarming way. Posts that were supposed to go out at 9 a.m. are still sitting in “waiting” at noon, and the most common reaction is to assume something is wrong with those specific posts, when the actual problem is that the every-minute check itself simply stopped running an hour and a half ago and nobody noticed.

That gap between “the scheduler is down” and “someone realizes the scheduler is down” is exactly what a heartbeat check closes. It’s a small, boring piece of monitoring, and it’s the difference between catching an outage in minutes and catching it when a client asks why nothing’s been posted all day — or worse, when nobody asks at all and a month goes by with a publishing gap nobody can explain after the fact.

Why Waiting Items Alone Aren't a Reliable Signal

It’s tempting to treat a pile of overdue “waiting” items as the heartbeat itself — if the scheduler were running, they’d have posted, so a backlog means it’s down. That reasoning is directionally right but too slow in practice: by the time a visible backlog has accumulated, the outage has usually already been running for a while, because most posting cadences space content out by hours, not minutes. A scheduler that died forty minutes ago might only show one or two overdue items so far, easy to dismiss as “probably about to post any second,” when actually nothing is coming.

The overdue-items signal also can’t distinguish between “the scheduler tick isn’t running at all” and “the scheduler tick is running, but something else is broken” — a stuck database connection, a broken queue setting, a workflow misconfiguration that’s silently rejecting every item it touches. Both produce the same symptom of things not posting, but they need completely different fixes, and conflating them wastes the first, most valuable minutes of troubleshooting.

What a Heartbeat Actually Checks

A heartbeat check is narrower and more direct than watching the queue: it verifies that the every-minute tick itself is executing, independent of whether any individual item is due or successfully posts. Each time the scheduler’s loop runs, it can record that fact somewhere durable — a timestamp written to a database row, a small marker file touched on disk, or a dashboard indicator that updates on the same cadence. The check that matters isn’t “did a post go out,” it’s “did the clock tick,” and those are genuinely different questions with different failure causes behind them.

This distinction is exactly why a dashboard-level heartbeat indicator is worth having even when your queue looks perfectly healthy: it answers the process-level question directly, rather than making you infer process health from publishing outcomes that lag behind the actual failure by however long your posting cadence happens to be.

Reading the Heartbeat Timestamp Correctly

A heartbeat is only useful if you know what “stale” means for it, and that threshold should track the check interval, not some arbitrary round number. Since the scheduler tick is meant to run roughly every minute, a heartbeat timestamp more than two or three minutes old is a real signal something’s wrong — that’s enough buffer to absorb a single slow tick without false-alarming, but tight enough to catch a genuine outage within a few minutes rather than a few hours. A heartbeat that’s twenty minutes stale isn’t a maybe; at that point the process is almost certainly not running at all, and the diagnosis moves from “is something wrong” to “confirm the process is dead and restart it.”

Where teams get this wrong is setting the staleness threshold too loose — treating anything under an hour as fine — which defeats most of the value, since it just recreates the same lag problem that watching overdue queue items already has, dressed up as a more precise-sounding number.

Checking From the Server Side Directly

The dashboard heartbeat is the convenient check, but on a self-managed VPS or dedicated server it’s worth knowing the direct process-level check too, since it doesn’t depend on the dashboard’s own reporting path being healthy. A quick `ps aux | grep schedule:work` confirms the process is actually resident in memory right now — if that comes back empty, nothing else matters, the process is simply not running and needs restarting through whichever supervisor manages it. If you’re running it under systemd, `systemctl status` gives the same answer along with how long it’s been up, which as a side effect also tells you whether it recently crashed and auto-restarted.

For deployments running on OS cron instead of a persistent process — the shared-hosting path, where long-running processes aren’t allowed — the equivalent check is confirming the cron job itself is firing, which usually means checking the host’s cron execution log or a log file the job writes to on each run, since there’s no persistent process to inspect with `ps`.

Setting Up External Monitoring on Top of the Heartbeat

An internal heartbeat is only useful if someone actually looks at it, and the honest failure mode for most teams isn’t the scheduler dying — it’s the scheduler dying at 2 a.m. and nobody checking the dashboard until the next afternoon. That’s the case for pointing an external uptime monitor at a heartbeat endpoint specifically, rather than relying purely on eyeballing a dashboard indicator. If the scheduler exposes (or you build) a lightweight endpoint that reflects the same heartbeat timestamp, an external monitor pinging it every few minutes can alert you the moment it goes stale, independent of whether anyone happens to be looking at the dashboard at that exact time.

This is a small amount of setup for a disproportionate amount of peace of mind — the alternative is discovering an outage only when someone downstream notices the silence, which is always later than you’d want and usually more visible than you’d like. Most general-purpose uptime monitoring tools already support this pattern natively — a simple periodic HTTP check with an alerting threshold is standard functionality, and none of it needs to be built specifically for this use case, only pointed at the right endpoint with a sensible staleness window configured.

A Concrete Example of Catching an Outage Early

Picture a deploy that goes out at 2 p.m. — a routine update to an unrelated part of the application — and the deploy script restarts the application server but, through an oversight in the script, never restarts the separately-supervised `schedule:work` process. Nothing about the deploy itself errors out, nothing in the deploy log flags a problem, and the site continues serving pages normally, because the scheduler process and the web server are entirely separate concerns from the deploy’s point of view. The only thing that’s actually broken is the one thing the deploy script wasn’t watching.

With a heartbeat monitor in place, that gap surfaces within minutes: the timestamp stops advancing at 2 p.m., the external monitor’s staleness check trips a few minutes later, and someone gets an alert before a single scheduled post has even missed its slot yet, since the next queued item might not have been due until 3 or 4 p.m. anyway. Without the heartbeat, the exact same outage is discovered however many hours later someone happens to check the Queue & Log and notices a growing pile of overdue items — by which point the fix is identical, but the wasted posting window is entirely avoidable and entirely a function of how quickly the gap was noticed rather than how quickly it was fixed.

Distinguishing a Dead Process From a Stuck One

Not every heartbeat failure means the process is gone entirely — sometimes it’s technically still running but stuck, wedged on something that never completes and never lets the loop advance to its next tick. This looks different from a dead process in a specific way: `ps aux` or `systemctl status` will show the process as alive, possibly with a long uptime, while the heartbeat timestamp keeps getting older. A dead process needs a restart; a stuck one usually needs the same restart plus a look at whatever it was doing right before it wedged, since simply restarting without investigating tends to let the same stuck condition recur on the next occurrence of whatever triggered it.

Job-level timeouts exist precisely to prevent this category of problem at the individual-job level — a single job that runs past 300 seconds gets killed rather than allowed to hang indefinitely — but a stuck scheduler loop itself, as opposed to a stuck individual job, is a different failure surface and worth checking for separately rather than assuming the timeout protects against every form of “stuck.”

Building Heartbeat Checks Into Routine Habits

The most reliable version of this isn’t a one-time setup you configure and forget — it’s a habit of glancing at the heartbeat indicator whenever you’re already in the dashboard for something else, plus the external monitor as the backstop for the hours nobody’s looking. Teams that treat heartbeat health as part of their normal daily check-in, alongside the Queue & Log’s waiting-versus-posted counts, tend to catch outages within minutes; teams that only think about it after a client complaint tend to have already lost a day of posting cadence by the time anyone looks.

The check itself costs almost nothing — a glance at a timestamp — and the cost of skipping it is a silent scheduler that can sit down for hours without anyone knowing, quietly turning a five-minute fix into a multi-hour backlog that then needs its own separate recovery plan once someone finally notices. For a team running the scheduler on behalf of clients specifically, that backlog isn’t just an internal inconvenience either — it’s a visible gap in a client’s publishing history that’s much harder to explain after the fact than the outage itself would have been to fix in real time.

Where to Go Next

Heartbeat checks are the early-warning layer for everything else the scheduler is responsible for — queueing, cadence, workflow chaining all assume the underlying tick is actually alive. For the full picture of how those pieces connect, see Scheduling and Workflow Automation: The Complete Guide.

Leave a Reply

Your email address will not be published. Required fields are marked *

Services Built for Expansion

Smart Bots Built for Real Impact

Lose away off why half led have near bed. At engage simple father of period others except. My giving do summer of though narrow marked at. Spring formal no county ye waited.
You have been successfully Subscribed! Ops! Something went wrong, please try again.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Support

Powered by Joinchat