how it works
most cron monitors ask you to declare a period and a grace period per job, and then page you when you guessed wrong. heartbeet doesn't ask; the beets learn each job's rhythm and its natural variability from the heartbeats themselves.
the beets learn a rhythm, not a number
every heartbeat updates a bayesian model of the gap between that job's heartbeats (a normal-inverse-gamma posterior over the gap distribution, if you want the term to search for). that gives the beets two things a configured interval can't: the job's typical rhythm and how much it naturally wobbles. a backup that lands within seconds every night gets a tight deadline; a queue worker that drifts ten minutes either way gets a looser one. nobody types either in; the beets figure it out on their own.
when do they page?
you set one number, per project: how many false pages per year you'll tolerate (one, by default). the beets turn that rate into a deadline for each job, scaled to its own rhythm, so a 30-minute job and a monthly job are each equally unlikely to page you falsely. when a job stays silent past its deadline, you get an email. lower the rate for fewer interruptions and slower detection; raise it for snappier paging.
a couple of floors keep this sane: a minimum page window (so a very fast job can't page you over a few seconds of jitter) and a jitter tolerance the beets always wait out. both are project settings; on a paid plan you can also tune them per job.
cold start
before the second heartbeat there is no gap to learn from. a brand-new job is bounded by the project's cold-start window (24h by default); if your job is slower than that, send a coarse hint on the first heartbeat (?hint=weekly, ?hint=monthly, ?hint=yearly…). a hint counts as roughly one pseudo-heartbeat of evidence; the first few real heartbeats after that dilute it quickly, though it keeps a little influence while the job's history is short. the beets never pretend to know a rhythm they haven't observed.
arrhythmia, before the flatline
on the paid plans the beets also watch for degradation: two consecutive heartbeats both arriving later than the beets expected (but within the deadline, so you weren't paged). it could be an early warning that something is slowing down before it goes fully silent.
silence is never swallowed
- muting a job (or a tag) silences pages but keeps recording; when you unmute, the beets show you what went red while it was muted and ask whether to page it, instead of deciding for you.
- pausing is explicit and deploy-shaped:
POST /pause/<job>(or a whole tag at once with?tag=) ahead of planned disruption. a pause has two windows: a drain, where heartbeats still arriving prove the old process is alive but can't cancel the pause, and a wait, the quiet budget while the disruption happens. when the pause lifts, the beets don't page on the first instant of silence; the job gets one normal heartbeat window (its usual rhythm plus grace period, learned per job) to find its feet. - a job you've retired on purpose can be decommissioned: it leaves the dashboards and the beets stop expecting it. if a decommissioned job sends a heartbeat again much later (heartbeats in the first hours after a decommission are ignored as shutdown stragglers), it's revived: back on the dashboard, watched again, and you get an email about it, because a job that's still running somewhere is something you want to know about.
and if you stop paying
the beets never stop watching a live job. if a paid plan lapses, the free limits come back: growth freezes (no new projects, API keys, or jobs beyond the free caps), extra dashboards turn read-only, extra paging recipients go quiet, and history shortens. but every job you were monitoring keeps being watched, and you keep being paged. a silence monitor you can't trust to keep watching isn't a silence monitor.