Open-source website monitoring and public status pages, built entirely on Cloudflare Workers.
Please Note: This project is in early development and not yet production-ready. Use at your own risk.
Multiple Workers collaborate via Cloudflare Queues, Durable Objects, and Pipelines:
flowchart TD
Scheduler["Scheduler (cron, every 1 min)"] --> CheckQueue["bitwobbly-check-jobs queue"]
CheckQueue --> Checker["Checker Worker<br/>HTTP checks + incident management (Durable Object)"]
Checker --> AlertQueue["bitwobbly-alert-jobs queue"]
AlertQueue --> Notifier["Notifier Worker<br/>Webhooks / email (Resend)"]
App["App Worker (React dashboard + REST API)"] --> AppTasks["UI, auth, CRUD for monitors/status pages/notifications/issues"]
App --> KV["Public status page snapshots cached in KV"]
Ingest["Sentry Ingest Worker (SDK-compatible issue ingestion)"] --> Envelopes["Receives Sentry SDK envelopes"]
Ingest --> Storage["Stores raw payloads in R2 + writes manifests to Pipelines"]
Ingest --> SentryQueue["bitwobbly-sentry-events queue"]
SentryQueue --> Processor["Sentry Processor Worker<br/>event grouping + fingerprinting"]
Processor --> D1["Groups events into issues, writes to D1"]
Alongside the workers, we have some infrastructure that is not part of the core system but would be if you were using those particular services. This includes:
infra/dashboard-- Superset dashboard with a Trino query engine for querying the data catalog and visualising data.infra/cognito-email-sender-- A CDK setup for deploying a custom AWS Lambda function to send emails via Resend, used for Cognito user pool custom email messages.
| App | Purpose |
|---|---|
apps/app-worker |
React dashboard + API. Manages monitors, status pages, notification channels, issue tracking projects, and auth. |
apps/scheduler-worker |
Cron-triggered dispatcher. Finds due monitors and enqueues check jobs. |
apps/checker-worker |
Queue consumer. Performs HTTP checks, tracks failures, opens/resolves incidents via Durable Objects, writes metrics to Analytics Engine. |
apps/notifier-worker |
Queue consumer. Delivers alerts via webhooks and email (Resend API). |
apps/sentry-ingest-worker |
Sentry SDK-compatible ingestion endpoint. Parses envelopes, stores raw payloads in R2, publishes to Pipelines and queue. |
apps/sentry-processor-worker |
Queue consumer. Extracts events from R2, computes fingerprints, groups into issues, writes to D1. |
| Package | Purpose |
|---|---|
packages/shared |
Drizzle ORM schema (16 tables), database factory, utility functions. |
- Cloudflare D1 -- SQLite database
- Cloudflare KV -- status page snapshot cache
- Cloudflare R2 -- raw Sentry envelope storage
- Cloudflare Queues -- job dispatch between workers
- Cloudflare Pipelines -- durable ingestion buffering and SQL transformation
- Cloudflare Durable Objects -- incident coordination state
- Cloudflare Analytics Engine -- latency/uptime metrics
- Resend -- transactional email delivery
- Node.js 24+
- pnpm 10.27.0 (
corepack enable && corepack prepare pnpm@10.27.0)
pnpm install
pnpm db:migrate:local
pnpm devThis runs all core workers concurrently via Turbo. The dashboard is at http://localhost:5173.
pnpm dev:app # Dashboard + API (port 5173)
pnpm dev:scheduler # Cron dispatcher (port 8788)
pnpm dev:checker # HTTP checks (port 8787)
pnpm dev:notifier # Email/webhook alerts
pnpm dev:sentry-ingest # Sentry SDK ingestion
pnpm dev:sentry-processor # Event groupingWrangler's simulator handles D1, KV, Queues, and Durable Objects locally. State persists in .data/ at the workspace root.
Cron triggers don't auto-run locally. Test monitors via the "Check Now" button or:
curl "http://localhost:8788/cdn-cgi/handler/scheduled"For email notifications, create apps/notifier-worker/.dev.vars:
RESEND_API_KEY=re_xxxxx
All workers deploy to Cloudflare via Wrangler. See docs/SETUP.md for full resource provisioning steps.