Comparison · vs Cronhub
RunWisp vs Cronhub: run the job, don't just ping about it.
Cronhub is a hosted service that triggers jobs over webhooks and watches for heartbeat pings from your cron. RunWisp is a self-hosted daemon that runs the process itself and records the result. One's a watcher in the cloud; the other's a runner on your box.
Should you switch?
The 10-second version. Skim, decide, scroll down for the receipts.
Consider RunWisp if
- You'd rather run the job than trigger it over a webhook and hope it landed.
- Job metadata — when it runs, whether it failed — shouldn't live on a third party's servers.
- The box is air-gapped, on-prem, or behind a strict egress firewall.
- You want the real stdout/stderr and exit code, not just “a ping arrived.”
- Per-monitor pricing that climbs with your job count isn't the model you want.
- You also need long-running services supervised, not just scheduled jobs watched.
Stay on Cronhub if
- You need an external watchdog that survives the whole box dying — the one thing an on-host daemon can't do.
- You watch jobs across many machines and want one hosted pane of glass.
- Zero install matters: no binary to ship, no daemon to keep alive.
- Public, hosted status pages are part of what you're buying.
- You're monitoring cron you don't control — a managed platform, someone else's server, a router.
Yes / no, at a glance
Yes / no, both columns win on something.
| Feature | Cronhub | RunWisp |
|---|---|---|
| Runs the job itself | triggers / watches over HTTP | executes the command |
| Captures stdout / stderr + exit code | ping only | |
| Self-hosted; data stays on your box | hosted SaaS | local SQLite |
| Works with no outbound internet | needs the ping to reach them | |
| Free, no per-monitor pricing | ~ free tier, then paid | GPL binary |
| Cron scheduling | | 5/6-field + aliases |
| Retries with backoff | | constant / linear / exp |
| Overlap policy | | skip / queue / terminate |
| Long-running services | monitoring only | [services.*] |
| Failure notifications (Slack, email) | | |
| Dashboard | hosted | self-hosted Web UI + TUI |
| External watchdog survives host death | pings from off-box | runs on the host |
| Zero install / nothing to run | | ship a binary |
| No server to maintain | managed | you run the daemon |
| Public status pages | | |
| One pane of glass across many machines | | ~ one daemon per host |
| Monitors cron you can't supervise | managed platforms, routers | |
Pros & cons
What Cronhub does better
- External monitoring survives the whole box dying — the ping comes from off-site, so a dead host is exactly what it catches.
- Nothing to install or run. Sign up, paste a URL into your crontab, done.
- Hosted dashboard and public status pages, maintained for you.
- One place to watch jobs across dozens of machines — RunWisp is one daemon per host.
- Monitors cron you can't put under a supervisor: a managed platform, someone else's server, a router.
- A managed service with an SLA, not a process you babysit.
What RunWisp adds
- Runs the actual process. “it ran” and “it succeeded” are the same fact, not a ping you hope fired.
- Captures stdout / stderr and the real exit code on every run — no
&& curlto bolt on or forget. - Everything stays on your box: schedule, timing, and captured logs in local SQLite. No job metadata on a third party.
- Works with no outbound internet at all — air-gapped, on-prem, behind a strict egress firewall.
- Free. A GPL binary you own, not per-monitor pricing that scales with your job count.
- Retries with backoff,
on_overlap, and catch-up after downtime — the job's behaviour, not just its heartbeat. - Coalesced failure notifications: five flaps become one Slack message plus a summary, not five pages.
- Supervises long-running services in the same config, not only scheduled jobs. One binary on Linux, macOS, WSL, Docker.
The simple case
Nightly backup at 03:00. Cronhub watches for a ping the job has to send after it runs; RunWisp runs the job and records exit code, duration, and output on its own.
# crontab -e, with a Cronhub monitor ping bolted on
0 3 * * * /usr/local/bin/backup.sh \
&& curl -fsS https://cronhub.io/ping/<uuid> # runwisp.toml — the daemon runs it and records the result
[tasks.nightly-backup]
cron = "0 3 * * *"
run = "/usr/local/bin/backup.sh" Production-grade
Same backup, hardened. On the left the timing is start/finish pings and the policy — grace period, alert routing — lives in Cronhub's dashboard; on the right every knob is a named field in a file you commit to git. A hung run trips timeout without a second ping to babysit.
# crontab — start + finish pings so Cronhub can time the run.
# Grace period, alert routing, and the expected schedule
# all live in Cronhub's dashboard, not in this file.
0 3 * * * curl -fsS https://cronhub.io/start/<uuid>; \
/usr/local/bin/backup.sh \
&& curl -fsS https://cronhub.io/finish/<uuid> \
|| curl -fsS https://cronhub.io/fail/<uuid> # runwisp.toml — every knob is config-as-code, in git
[tasks.nightly-backup]
description = "Snapshot the data volume to off-site storage"
cron = "0 3 * * *"
on_overlap = "skip" # never two backups at once
timeout = "55m" # a hung run fails, not runs forever
retry_attempts = 2
retry_delay = "30s"
retry_backoff = "exponential"
keep_runs = 60 # two months of history
notify_on_failure = ["slack-ops"]
run = "/usr/local/bin/backup.sh" Migration cheat sheet
Concrete mappings from Cronhub concepts to runwisp.toml. The one you can't map — an off-box watchdog — is called out below.
| Cronhub | RunWisp |
|---|---|
&& curl .../ping/<uuid> monitor ping | Drop it. RunWisp records the real exit code natively. |
| Cronhub scheduler webhook (HTTP trigger) | [tasks.*] with run = — executes the command directly |
| Grace period (dashboard) | timeout = "55m" + crashed-run detection |
| Expected-schedule assertion | cron =; a firing missed during downtime rides catch_up + notify_on_failure |
| Hosted dashboard | Self-hosted Web UI, or runwisp tui over SSH |
| Cronhub email / Slack integration | notify_on_failure = ["slack-ops"] (Slack / Telegram / Discord / email / webhook) |
| Monitor status healthy / failing | Run-history rows: status, duration, exit code, captured logs |
| Start / finish pings to time a run | Duration recorded automatically per run; timeout fails an overrun |
| One dashboard watching N machines | One runwisp per host — you gain local capture, you lose the single pane of glass |
Gotchas
If the box dies, RunWisp dies with it
RunWisp runs on the host it watches. It catches a failed run, a crash, or a firing missed while the daemon was down (that lands as a missed run and rides notify_on_failure). But if the whole machine loses power or its network, there's nothing left on it to send the alert. That silence is exactly what an external heartbeat like Cronhub is for. If total host death is in your threat model, keep an off-box watchdog — the two aren't mutually exclusive.
Your schedule metadata stays on your box
With a hosted monitor, when your jobs run and whether they succeeded is data on someone else's servers. RunWisp keeps schedules, run timing, exit codes, and captured output in a local SQLite file. For regulated, on-prem, or air-gapped environments that's the difference between allowed and a non-starter.
A ping is not the work
Cronhub's scheduler fires an HTTP request and its monitor watches for one; both are a proxy for the job. If the job crashes after the ping, or the && curl is dropped in a refactor, the dashboard stays green. RunWisp runs the process, so the exit code it records is the job's, not a heartbeat's.
Nothing to remember to add
The classic monitor failure is a job that never got its ping line, or lost it. RunWisp needs no cooperation from the job: add the task, and history plus alerts are automatic — there's no URL to paste and no curl to keep in sync.
FAQ
Not for total host death. RunWisp runs on the box it watches, so it catches a failed run, a crash, or a firing missed while the daemon was down — that lands as a missed run and rides notify_on_failure. But if the whole machine loses power or its network, nothing on it can send an alert. That silence is exactly what an external heartbeat like Cronhub catches, because its ping comes from off-site. If total host death is your threat model, keep an off-box watchdog; RunWisp and an external monitor aren't mutually exclusive.
Yes. Leave the ping lines in your crontab, add the RunWisp task next to them, and compare for a week. RunWisp's run history shows you the real exit codes while Cronhub keeps watching the pings. Cut the && curl once you trust the local capture.
No. The daemon is GPL-3.0-or-later and free to self-host, with no per-monitor or per-job pricing — the thing that makes a hosted monitor's bill climb as you add jobs. You run it on hardware you already have.
Everything stays on the box: schedules, run timing, exit codes, and captured stdout/stderr live in a local SQLite file. Nothing about when your jobs run or whether they failed leaves your infrastructure. That matters for air-gapped, on-prem, or regulated setups where a hosted monitor is a non-starter.
Not in the external sense. A dead-man's-switch like Cronhub's watches from off-site and fires when an expected ping doesn't arrive, which is how it survives your host dying. RunWisp watches from inside: it knows a run failed, crashed, or was missed after downtime, and alerts on those. Same goal — know when a job didn't run — different vantage point. Overlapping, not identical.
RunWisp doesn't trigger a webhook; it runs the command. Where Cronhub's scheduler POSTs to an endpoint you host and you wire that to your job, RunWisp puts the schedule and the command in one [tasks.*] stanza and executes it directly. Fewer moving parts: no receiver to keep up, and no gap between “the webhook fired” and “the job actually ran.”
Yes. One static Go binary, around 25 MB idle, no runtime and no account. Same TOML and same Web UI port on Linux, macOS, WSL, and Docker. The only platform-specific piece is the autostart wrapper (systemd unit on Linux, launchd plist on macOS, init script in containers).
More comparisons: RunWisp vs cron · RunWisp vs systemd timers · RunWisp vs supervisord .
Run the job. Keep the receipts. Skip the middleman.
Install the binary, put your schedule and command in one runwisp.toml stanza, and watch the first run — exit code, duration, logs — land in your own dashboard.