Cronhq - Cron jobs that actually run

Cron jobs fail in silence. Two servers run the same crontab and your billing job fires twice. A job dies and nobody notices for weeks. Cronhq is a scheduler built around one guarantee: exactly-once execution, enforced by Postgres locks — not best-effort. Around it: retries with backoff, HMAC-signed webhooks, heartbeat monitors for jobs we don't run, and alerts that fire once on failure and once on recovery. Rust on Postgres. MIT-licensed, self-hostable, same image we run. Free tier: 5 jobs.

Add a comment

Replies

Best
Hi Product Hunt šŸ‘‹ I'm Michael, and I built Cronhq alone over the past several months. It started with a bug I kept watching people hit at client gigs. A team scales their app from one box to two. Both boxes have the same crontab. The nightly billing job now runs twice, and a customer gets charged twice. Nobody finds out from a dashboard — they find out from an angry support ticket. The other half of it is quieter and worse: a job that just stops. No crash, no page, no alert. Six weeks later someone notices the reports have been empty since March. Cronhq is my attempt to make both of those failures structurally hard instead of merely unlikely. What's under the hood: → Exactly-once execution. Every due run is claimed through a Postgres lock row with an expiry deadline, and next_run_at moves forward BEFORE dispatch. Two workers cannot fire the same run. If a worker dies holding the lock, the expiry lets another one take over rather than the run being lost. → Retries with backoff, per job — max attempts, delay and timeout are config, not a try/except you copy-pasted from Stack Overflow. → Alerts that dedup on transitions, not state. One alert when a job starts failing, one when it recovers. Not 47 pages at 3am. → Signed webhooks. HMAC-SHA256 over timestamp.body, with per-job secrets you can rotate without downtime, so your endpoint can prove the request came from us. → Heartbeat monitors — a dead-man's switch for jobs we DON'T run. Ping a URL from your existing cron; if the ping doesn't land inside the window, you get alerted. Absence is the thing that's hard to detect. → Cron-as-code. Put your schedules in cronhq.yaml, run `npx cronhq sync`, and `npx cronhq tail` to watch executions stream live. The stack is Rust (axum + sqlx + tokio) for the scheduler, worker and API, Postgres as the only coordination primitive, no Redis, no Kafka, no scheduler-of-schedulers — and a Next.js dashboard. It's MIT licensed and self-hostable with one docker-compose. The self-hosted image is the same image the cloud runs; there are no features hidden behind a flag. Free tier is 5 jobs, paid starts at $5. Two things I'd genuinely love your take on: 1. Is "exactly-once" the right thing to lead with, or does it read as too in-the-weeds outside of backend circles? 2. What would you need to see before you'd trust this with a job that actually moves money? I'll be here all day answering everything. Thanks for reading šŸ™