Self-Hosted Uptime Monitoring Tool
Lightweight website monitoring tool with real-time dashboard, SSL certificate tracking, configurable alerts, and 11 REST API endpoints — self-hosted on a single machine with zero external dependencies.
Problem
Small businesses and developers need website uptime monitoring but enterprise tools (Datadog, Pingdom) are expensive for simple use cases. The goal was to build a lightweight, self-hosted monitoring tool that tracks HTTP uptime, SSL certificates, and response times with zero external dependencies.
Solution
Built a complete monitoring tool with FastAPI backend, real-time dark-themed dashboard, configurable alerting (email + webhooks), and automatic recovery detection. The entire stack runs on SQLite — no external database, no message queue, no Redis. Currently monitoring 5 sites in production with a 2MB+ database of historical check data.
Architecture
APScheduler (60s sync) → HTTP/SSL Checks → SQLite → FastAPI → Dashboard
│ │ │ │
Job Management aiohttp async SQLAlchemy Chart.js
Dynamic intervals SSL validation Cascade FK Auto-refresh
Recovery detection 10s timeout Alert log Status cards
The scheduler dynamically syncs monitor configurations every 60 seconds, adding or removing check jobs as monitors are created or deleted through the API.
Key Decisions
SQLite over Postgres. For a self-hosted monitoring tool, zero-dependency deployment wins. SQLite handles the write patterns (one check per monitor per interval) easily, and the entire database is a single file that can be backed up with cp.
Async everything. HTTP checks and alerting are all async with aiohttp. This means 50+ monitors can run their checks concurrently without blocking, keeping memory usage under 50MB.
State-based alerting. Rather than firing alerts on every failed check (which creates alert fatigue), the system tracks monitor state transitions. You get one “down” alert, one “recovered” alert, and SSL expiry warnings at 30/14/7 day thresholds.
Results
- 11 REST API endpoints for full CRUD + statistics
- Real-time dashboard with auto-refresh, response time charts, and uptime percentages
- Email + webhook alerting with deduplication
- SSL certificate monitoring with multi-threshold warnings
- Currently monitoring 5 production sites (4 up, 1 down at time of writing)
- 19 tests passing (100% of test suite)
- Under 50MB memory footprint
- Runs 24/7 via launchd on port 8070
How This Scales
This is currently a single-tenant self-hosted tool. The path to a multi-tenant SaaS product includes:
- User authentication — Add Auth.js or API key scoping so multiple users can manage their own monitors independently.
- Multi-tenant isolation — Tenant-scoped database queries, per-user dashboards, and quota enforcement.
- Public status pages — Shareable URLs like
status.yourcompany.comshowing real-time uptime for each monitor. - Billing integration — Stripe subscription tiers based on monitor count, check frequency, and alert channels.
- Distributed checks — Run monitoring probes from multiple geographic regions to detect localized outages.
- Postgres migration — Replace SQLite with Postgres for concurrent writes at scale while keeping the single-file dev experience.
Tech Stack
- Backend: Python 3.13, FastAPI, uvicorn
- Database: SQLAlchemy + SQLite (2MB+ production data)
- Scheduling: APScheduler with AsyncIOScheduler
- Monitoring: aiohttp (async HTTP), Python ssl module
- Frontend: Vanilla JS, HTML/CSS, Chart.js
- Deployment: launchd service, auto-start on boot