architecture
How tower works
A prober Worker checks and mails; a page Worker serves the page and hands requests to it.
Two Workers
The prober runs on a cron each minute, runs the checks that are due, writes results to D1, sends alert mail through the send_email binding and answers the page over Workers RPC. The page Worker serves the page, /api/status, /beat/* and /relay/*, and hands what it receives to the prober.
A check's life
down_after runs in a row have failed.down_after runs in a row have failed, the check goes down and the change queues one DOWN mail in the outbox. The failure reason goes to that mail and the Worker log only, never the public page. A maintenance note suppresses alerts for its checks inside its window.up_after runs in a row have passed. Meanwhile the public page shows it down by name, with how long it has held that status, its uptime and its response times, while its address stays behind.up_after runs in a row have passed, the check is up again and the change queues one UP mail, so tower mails once when a check goes down and once when it recovers. Each mail waits in the outbox until it sends: a failed send is tried again on the next run.down_after or up_after runs in a row; a heartbeat goes down at its first missed deadline.Five check types
http
Requests an address and judges the response.
tcp
Opens a connection to a port. It sends no data.
dns
Resolves a name through 1.1.1.1 over DoH.
tls
Reads a zone's edge certificates through the Cloudflare API.
heartbeat
Waits for a request from your job within its interval plus a grace.
Names only
Failure reasons go to the alert mail and the Worker log only. Heartbeat and relay tokens are stored as sha256 hashes, so the plaintext never enters your config. A check that has not run recently reads as unknown, so a stopped cron cannot leave a stale green page.
Watching itself
all up with no body. An outside poller can also read /api/status, which reports the last run, the oldest unsent mail and stuck checks.Relays
POST /relay/incident, as HyperDX sends, and mails on transitions only. tower reads each alert's deduplication key as its key. A firing for a closed key opens it and mails FIRING. Titles, descriptions and keys reach the alert mail only, never the page or /api/status.duplicate. A sender that keeps re-notifying therefore holds the key open in silence, so set the relay's grace above the sender's re-notify gap, at most seven days.Limits
- A tcp check against a Cloudflare-proxied address, or one Cloudflare blocks, reads as down.
- A tcp check sends no data, so a service that accepts and then fails reads as up.
- A tls check covers edge certificates. An origin certificate failure shows as http 526.
- Checks run from one Cloudflare location per cron run, so a failure near it can read as down.
- Relays have no silences or maintenance windows.
- A relay holds at most 100 open keys. A firing past that is rejected, and one SELF-CHECK FAILING mail says so.
- If both Workers are dead, nothing mails, and only the missing digest says so.