Uptime Monitor Alerts
Persistent URL monitors with D1 history, cron checks, and email alerts on downtime - edge uptime monitoring starter
Extend the is-it-down pattern into a persistent monitor. Cron pings registered URLs, logs checks to D1, and sends email alerts when a URL transitions from up to down.
Features
- POST /monitors - register URL + alert email
- DELETE /monitors/:id - remove monitor
- GET /monitors/:id/history - check history and uptime percentage
- Scheduled checks every 5 minutes
API Reference
POST /monitors
{ "url": "https://example.com", "alertEmail": "you@example.com" }DELETE /monitors/:id
Remove a monitor.
GET /monitors/:id/history
Returns check history and uptime percentage.
Error Codes
400-INVALID_URL,INVALID_EMAIL,INVALID_BODY404-NOT_FOUND
Use Cases
- Lightweight uptime monitoring for side projects
- Learn Cron + D1 + send_email alert patterns on Workers
- Track uptime percentage over time for SLA reporting
Limitations
- Requires D1, Cron, and send_email bindings configured for your domain
- 5-minute check interval; not sub-minute alerting
- Single-region edge checks; not global multi-PoP consensus
Use in your project
Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/uptime-monitor-alerts.
import { DEFAULT_ALERT_FROM } from "../constants/defaults";import type { Env } from "../types/env";export async function sendDownAlert( env: Env, params: { alertEmail: string; url: string; statusCode: number; error?: string }): Promise<{ sent: boolean; error?: string }> { const from = env.ALERT_FROM_EMAIL?.trim() || DEFAULT_ALERT_FROM; const subject = `Monitor alert: ${params.url} is down`; const details = params.error ? `Error: ${params.error}` : `HTTP status: ${params.statusCode || "unknown"}`; const text = [ "Your uptime monitor detected a down transition.", "", `URL: ${params.url}`, details, "", "This alert was sent by the uptime-monitor-alerts experiment.", ].join("\n"); try { await env.EMAILER.send({ from, to: params.alertEmail, subject, text, }); return { sent: true }; } catch (error) { const message = error instanceof Error ? error.message : "Failed to send alert email"; return { sent: false, error: message }; }}export async function recordAlert( db: D1Database, monitorId: number, alertEmail: string, sent: boolean, error?: string): Promise<void> { await db .prepare("INSERT INTO alerts (monitor_id, alert_email, sent, error) VALUES (?, ?, ?, ?)") .bind(monitorId, alertEmail, sent ? 1 : 0, error ?? null) .run();}Deployment
Configure bindings
D1 DB, send_email binding EMAILER, cron */5 * * * *. Configure allowed sender/destination addresses in wrangler.
Test your deployment
See the experiment README for curl examples.
Local Development
cd apps/experiments/uptime-monitor-alerts
npm install
npm run devConfiguration
D1 DB, send_email binding EMAILER, cron */5 * * * *. Configure allowed sender/destination addresses in wrangler.