Nobody noticed until the restore failed. PulseWatch watches the jobs you schedule: cron jobs, queue workers, nightly backups. It tells you when one stops running, or keeps running without doing its work.
Your job ends by sending one HTTP request, called a ping. If that ping stops arriving, or the numbers it carries fall out of range (a nightly export reporting 0 rows instead of its usual 1,400), every alert channel on that monitor fires.
This is the whole integration. Append it to any cron job:
curl -fsS -m 10 --retry 5 https://pulsewatcher.up.railway.app/ping/<your-token><your-token> is a placeholder. Your real ping URL appears as soon as a monitor exists.
&&only pings if your job exited 0, so a crash never looks like success.-fsSquiet when it works, loud when it fails, so cron mails you only on real errors.--retry 5a dropped packet on your side does not become a false alarm.A worked example, nothing to copy. A real crontab line reporting its row count, and the dashboard rows it produces:
# nightly backup, reports its row count on success 0 3 * * * ./backup.sh && curl -fsS "https://pulsewatcher.up.railway.app/ping/<your-token>?rows=$(wc -l < dump.sql)"
Nightly DB backup
Queue worker heartbeat
Invoice sync
Illustrative dashboard, not a live feed.
One command lists every cron job, systemd timer and CronJob on a machine, and tells you which ones nothing is watching: sorted so the nightly backup is above the cache warm.
curl -fsSL https://pulsewatcher.vercel.app/audit.sh | shRead-only. Nothing about your machine is sent anywhere, not to us, not to anyone. We are asking you to pipe a script into your shell, so the source is published in full, it is one file, and a test asserts that file is byte-for-byte what the URL serves. What it reads, and what it never does.
Attach numbers to the ping and PulseWatch keeps them. Row counts, error counts, bytes written, anything you can measure. Run duration is recorded for you.
Add them as query parameters on the success ping. Nothing else to install:
curl -fsS "https://pulsewatcher.up.railway.app/ping/<your-token>?rows=1400&duration_ms=8200"
Floor
Alert if it drops below a number you set. rows ≥ 1000.
Ceiling
Alert if it climbs above one. errors ≤ 5.
Deviation
Alert if it falls well below normal for that weekday or hour, without you picking a number.
The alert you get looks like this:
Nightly export is DOWN
rows = 245, which is 82% below the Sunday median of 1,380 (8 samples).
The job exited 0 and the ping arrived on time. Only the number was wrong.
Deviation compares each run against the same weekday or hour, so a quiet Sunday is not treated as a failure. How metrics work →
curl -fsS -m 10 --retry 5 https://pulsewatcher.up.railway.app/ping/<your-token>For cron jobs, queues and backups: anything that should run on a schedule. Your code pings us; silence past the grace window means trouble. An explicit /fail ping alerts immediately, and a /start ping enables run-duration and max-duration timeouts.
We request your URL as often as every 60 seconds. A bad status code, timeout or connection failure, confirmed by a second attempt so a blip doesn't page you, and you hear about it first. Optional keyword and response-time (degraded) checks on Pro.
These are failures you'll actually catch. Everything listed here ships today.
Attach numbers to a ping (?rows=1400), then set a floor, a ceiling, or a baseline. A job that exits 0 having processed nothing still goes down. Baselines compare against the median of the last 14 runs and need Pro.
Signed webhooks (HMAC-SHA256) with a stable JSON schema. Slack and Discord URLs get native formatting automatically. Point one at your restart script instead of your inbox.
Down events group into an incident with a timeline, a duration, and the reason and evidence that triggered it. Add postmortem notes if you want; the skeleton is already there.
Per-monitor p50 and p95 rollups over time. A service that is slowly degrading shows up here well before it falls over.
Uptime monitors read the certificate on every check and warn you at 14, 7 and 1 day. No more Monday morning spent on a lapsed cert.
Plain intervals, or a cron expression with an explicit timezone. "Every weekday at 07:00 Europe/Paris" means exactly that. Maintenance windows mute alerts during planned work.
Publish a status page for the monitors you choose, and drop a live SVG uptime badge in your README. Both read from the same checks, so they never disagree.
Create, pause and query monitors with a key-authed API. Provision the same job across fifty machines in a loop rather than by hand.
Every run and state change is kept with its reason, evidence and log excerpt. Answer "what happened at 3am" without guessing, and watch mean time to recovery move.
Tag monitors, then filter or search across them. Monday morning you get an email with uptime, incidents, and whichever monitor did worst.
Email, Telegram and webhooks, several per monitor if you want. You get one alert when it goes down and one when it recovers. Nothing in between.
Bulk-import monitors and export everything as JSON. Your configuration is yours to take elsewhere.
Three monitors free, forever, with email alerts. That covers a side project’s backup, its deploy, and the nightly job you forget about.
Tag by client and publish a status page per project. Webhooks route each alert wherever that client lives. When someone asks "was it us?", the history answers.
Running the same cron on forty machines? Provision them over the REST API in a loop, tag them, and watch the whole fleet from one dashboard.
MAILTO= or a bash trap?It emails you when the job runs and prints to stderr. It says nothing when cron itself is down, when the box is off, or when the line never fired at all. Absence is the failure you care about, and absence sends no mail.
Good practice, and worth doing. But it can only report while the script is still alive. A kernel OOM-kill, a full disk, a hung mount, a machine that never booted: the trap never runs. A missed heartbeat is noticed from the outside, so "it didn't run at all" becomes a real signal instead of silence.
It watches your public URL, not your 3am cron. And HTTP 200 doesn't mean the work happened. A job can exit 0 having written nothing. A metric floor catches that. A pinger standing outside your system can't.
Start free, no credit card. Upgrade when you outgrow three monitors.
$0/mo
Forever
$7/mo
25 monitors · 30-day history
$19/mo
100 monitors · 90-day history
Billing is handled by Lemon Squeezy (merchant of record). Cancel anytime. Downgrade and any monitors over your new limit auto-pause, oldest first. Nothing is deleted. More in the FAQ.