Know when a scheduled job didn't run. Your jobs ping Crontide when they finish. If a ping is late, you get an alert.
Most job monitoring only works if the failure gets reported. In January 2017, GitLab.com lost over six hours of production data. When the team went to restore, the database backups weren't there. pg_dump had been failing because of a version mismatch, and the cron failure emails that should have reported it were being rejected by DMARC.
Crontide waits for the success signal instead. A job that crashed, hung, never started, or failed without saying so still triggers an alert, because the ping it owes never arrives.
It runs on your own server as one container plus Postgres. The ping API is Healthchecks-compatible, so scripts and tools that already ping Healthchecks, such as borgmatic, can switch by changing one URL. For .NET apps, a NuGet client pings automatically from Hangfire, Quartz.NET and BackgroundService jobs.
Status: M0, a placeholder. The image builds and shows the screens with canned data. The ping API and the schedule engine arrive in M1. See ROADMAP.md.
git clone https://github.com/hazeliscoding/crontide.git
cd crontide
docker compose up -d --buildThen open http://localhost:8080. The compose file starts Crontide and Postgres, nothing else. docker compose down -v removes both again, including the database volume.
# crontab: back up at 03:00, then report the exit code
0 3 * * * pg_dump app > /backups/app.sql; curl -fsS -m 10 --retry 5 https://cron.example.com/ping/5f3c9a1e-…/$?nightly-backup · 0 3 * * * · Europe/Berlin · grace 30m
Sep 23 03:00:41 up exit 0
Sep 24 03:00 late no ping yet
Sep 24 03:30 down alert sent to Discord #ops and email · both delivered
Sep 24 09:12:05 up exit 0 · recovered, alert sent
- Schedules by interval ("every 6 hours") or cron expression, in the job's time zone, with a grace period per job.
- Records every ping: start, success, failure, exit code, run time, and up to 100 KB of output.
- Alerts through Discord, email or a webhook when a job misses its grace period or reports a failure, and again when it recovers.
- Tracks delivery. Every alert records whether it arrived. A bounced email shows up on the dashboard instead of disappearing.
- Speaks Healthchecks.
/start,/fail,/log, exit codes and run IDs work the same way.
- One container plus Postgres.
docker compose up -d. No Redis, no queue, no other services. - No telemetry. The only outbound traffic is your alerts, plus an optional watchdog ping so something outside can tell you when Crontide itself is down.
- Open source, so you can check all of this.
Healthchecks is the mature open-source project in this space, with far more integrations and years of production use. If you want the full-featured option, use it. Crontide is a smaller, .NET-native alternative that accepts the same pings.
You need the .NET 10 SDK, Node 24 and Docker.
# web app: src/Crontide.Web
npm ci
npm start # dev server on http://localhost:4200
npm test # unit tests
npm run check # contrast and remote-asset checks
# server: repo root
dotnet test
dotnet run --project src/Crontide.Server # http://localhost:5025CI runs the same steps, builds the image, starts it with compose and checks the screens with Playwright.
Each alert channel is one folder: a sender, its settings and tests. Adding a channel (Slack, Telegram, ntfy, Matrix) is a good first contribution. The channel guide arrives with v0.2.
