monitoring
Cronitor logo

Should I self-host Cronitor?

NOT REALLYkeep paying

Healthchecks is excellent and installs in half an hour. Cronitor's solo tier is $2/mo. If your time is worth anything at all, the subscription wins — and the monitor watching your cron jobs shouldn't share fate with the box running them.

The math (nothing hidden, including your time)

Cronitor (Business)$2.00/mo
VPS share + storage−$0.50/mo
Your maintenance: 10 min/mo at $20/h−$3.33/mo
Net saving$-1.83/mo
Setup: 35 min measured (one-time)$11.67
Break-evennever
Markup Index (price ÷ real self-host cost)0.5×

Price: source, checked 2026-08-05. Inputs are stored in git; every number above is derived, never hand-written.

What you lose

  • Independence: self-hosted on the same infra it watches, an outage takes out the alarm too
  • $24/yr of not thinking

What you're paying Cronitor for

  • dead-man-switch cron monitoring
  • alerting (email/webhook/Slack)
  • status badges
  • schedules/grace windows
Healthchecks running from the boot-verified compose file
Healthchecks, running from the compose file on this page — screenshot from our verified instance, not marketing material.

Ranked alternatives

A dead-man's switch for every cron job you own, with no monitor quota and no per-check billing.

healthchecks/healthchecks · ★ 10,231 · last commit 1d ago · BSD-3-Clause

Hardware

Runs comfortably on Raspberry Pi.

The tested compose file (our evidence, CI-booted)

# Healthchecks — cron job monitoring (tested against Cronitor's job list; see the verdict
# for why the $2/mo subscription out-competes your own attention)
services:
  healthchecks:
    image: healthchecks/healthchecks:latest
    container_name: healthchecks
    restart: unless-stopped
    depends_on:
      hc-db:
        condition: service_healthy
    environment:
      SECRET_KEY: 7f3a9c1e5b8d2f6a0c4e8b2d6f0a4c8e # throwaway test value
      SITE_ROOT: http://localhost:8089
      ALLOWED_HOSTS: "*"
      DEBUG: "False"
      DB: postgres
      DB_HOST: hc-db
      DB_NAME: hc
      DB_USER: hc
      DB_PASSWORD: hc
    ports:
      - "8089:8000"
    # No healthcheck override: the image ships its own (./fetchstatus.py probes
    # /api/v3/status/, which checks the DB connection — sqlite without a writable dir
    # fails it, which is why this compose brings postgres).

  hc-db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: hc
      POSTGRES_PASSWORD: hc
      POSTGRES_DB: hc
    volumes:
      - hc-pg:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U hc"]
      interval: 5s
      timeout: 5s
      retries: 12

volumes:
  hc-pg:

Want a guided install instead? caniselfhostit.com/cronitor has AI-agent prompts that assume a bare machine — that's their half of the stool, and it's good.

Verification

Protocol v1 · verified by zernonia on 2026-08-10 · setup measured at 35 min · AI assistant: claude-code (allowed & stated)

What broke

  • The image's built-in healthcheck probes the database connection, and the sqlite default has no writable path in the stock container — it 500s forever until you either mount the sqlite dir correctly or (better) give it the Postgres it actually wants
Full timed log
# Timed setup log: Cronitor → healthchecks

**Protocol:** v1 · **Verified by:** zernonia · **Date:** 2026-08-10
**Assistant:** claude-code · **Environment:** containerized runner, 2 vCPU class, Docker 29.3 / Compose v5.1

## Timeline

| Step | Time |
|---|---|
| Read upstream docs, draft compose with healthcheck | ~11 min |
| **Boot: all services healthy in 12 s (measured, `compose up --wait`)** | — |
| Endpoint-level workflow check (login/health/API serve) + re-run from clean volumes | ~11 min |
| **Total: ~35 min** | |

Boot and endpoint checks are machine-verified; `setup_min` is the wall-clock total for this
session including authoring, diagnosis and re-runs. Endpoint-level ≠ full human UI workflow —
dispute anything that doesn't reproduce (CONTRIBUTING.md).

## What broke

- The image's built-in healthcheck probes the database connection, and the sqlite default has no writable path in the stock container — it 500s forever until you either mount the sqlite dir correctly or (better) give it the Postgres it actually wants

## Verdict-relevant notes

- Same cheap-SaaS pattern as Pinboard: capability is all there; the economics simply never arrive. Run it if you already have a fleet and want internal-only pings.

Verdict history

  • 2026-08-10: unscored → NOT_REALLY — Initial verdict: Healthchecks is excellent and installs in half an hour. Cronitor's solo tier is $2/mo. If your time is worth anything at all, the subscription wins.