Uptime
The “Uptime” section watches the availability of external addresses and services through periodic checks — monitors. Open it from the activity icon in the left rail, or at /projects/{id}/monitors.
Who runs the checks
Checks are queued by the uptime scheduler, which runs in --mode=web, --mode=uptime, and --mode=all (not in --mode=ingest; see Process modes), and executed either by the built-in runner (--mode=uptime and --mode=all only) or by a remote probe in another region.
If the instance is split and neither role is present — say only --mode=web and --mode=ingest — monitors will show as enabled and nothing will check them. Such a process says so at startup: uptime checks are scheduled here but NOT executed in this mode.
Creating a monitor
The monitor list lives at /projects/{id}/monitors. The “New monitor” button (visible to a project team member — an operator — as well as an org owner/admin; see Roles and access) opens the form at /projects/{id}/monitors/new.
The form starts with a check type picker — HTTP, TCP, DNS, or Heartbeat. Each type has its own fields:
| Type | What it checks | Fields |
|---|---|---|
| HTTP | An HTTP(S) request to a URL; success is the response code and, optionally, body content | Method (GET/POST/HEAD), URL, Headers, Body, Expected status (comma-separated codes; empty = any 200–299), Body contains / Body not contains, Follow redirects, SSL alert (days before certificate expiry to warn) |
| TCP | Whether a TCP connection to host:port succeeds | Host, Port (1–65535) |
| DNS | Whether a name resolves and, optionally, matches an expected value | Hostname, Record type (A/AAAA/CNAME/MX/TXT), Expected value (optional) |
| Heartbeat | The reverse of the others: instead of Gotcha reaching out, your own application “checks in” periodically by pinging a dedicated URL. If it hasn’t checked in within the grace period, the monitor is considered down | Grace period (seconds, minimum 60) |
The type is fixed once a monitor is created — editing lets you change its settings, not its type.
For a Heartbeat monitor, the personal ping URL of the form {base_url}/uptime/hb/{token} — plus a ready-made curl cron line — is shown once, right after you create or regenerate the monitor. The token is stored hashed and can’t be shown again, so copy it then; if you lose it, use Regenerate token on the detail page to mint a new URL. A normal visit to the detail page shows a “regenerate to get a new URL” hint instead of the token.
*/5 * * * * curl -fsS -X POST https://gotcha.example.com/uptime/hb/6e1f...af92 >/dev/null
Add that to your application’s cron/systemd timer — every successful call resets the grace timer. GET is also supported and keeps working, but POST is the recommended form: the ping URL regularly gets hit by more than your cron job — forwarded in a chat, it gets fetched by a messenger’s link-preview bot or scanned by an antivirus proxy — and such automated visits always arrive as GET and are recognized by their headers/User-Agent; a request like that is rejected with 204 and never counts as “the service is alive”.
The token in the URL is the ping’s only secret. The /uptime/hb/{token} endpoint is deliberately unauthenticated and skips the request-origin check: it is not a browser form but an external call (cron, a systemd timer), and nothing but the address itself can protect it. That means anyone who knows the URL can send the “service is alive” signal — and the address ends up in your proxy’s access logs, in browser history, in crontab -l output, and in forwarded messages. Treat it like a password: don’t publish it, don’t paste it into tickets or chats. Rotation is only via Regenerate token on the monitor page (a project operator action): the old URL stops working immediately, the new one is shown once. An unknown token gets a 404, and the endpoint is rate-limited like any public one. GET is supported on purpose — so the signal can be sent from cron with a plain curl/wget and no flags — but the recommendation above to use POST still stands.
Interval, timeout, thresholds
- Interval — how often the check runs, in seconds (minimum 30).
- Timeout — how long to wait for a response, in seconds (1–120, and must be less than the interval).
- Retries — how many times to re-run a single failed check before it counts as a failure (0–10). Absorbs a transient blip (a dropped packet, a brief TLS hiccup) so it doesn’t flip the monitor or open an incident.
- Fail threshold — how many consecutive failed checks flip the monitor to down and open an incident.
- Recovery threshold — how many consecutive successful checks flip it back to up and close the incident.
- Remind every (minutes) — how often to resend a notification for a still-open incident (0 = never remind).
Thresholds are tracked independently per region — the monitor’s overall status is decided by the consensus rule below.
Regions and consensus
A monitor can be checked from more than one region — the built-in local region (running alongside the server) and any remote probes the organization has registered. The list of available regions and their checkboxes live in the same monitor form.
When a monitor has more than one region, its overall status is computed with a consensus rule:
| Consensus | Rule | When to use it |
|---|---|---|
| “Any region” | Down if at least one region is down | Strict: any single point of unavailability is already a problem |
| “Majority of regions” | Down if half or more of the decided regions are down | A compromise: tolerates a single regional blip |
| “All regions” | Down only if every region is down | Lenient: alert only on a total outage |
Important note about “Majority of regions” with an even number of regions: if exactly half the regions are down (e.g. 2 of 4), that also counts as down, not up — a deliberate fail-safe so the monitor is never shown green when half the fleet is reporting an outage.
A region only counts toward consensus once it has crossed its own fail or recovery threshold — before that it’s excluded from the tally.
Incidents
When a monitor’s region-aggregated status flips to down, an incident opens: it records the start time, a cause (the last error text), and the list of regions that are down. It stays open while any region remains down, and closes with a recorded duration once consensus returns to up.
An incident that opens during an active maintenance window is marked “in maintenance” and does not send a notification — so planned work doesn’t create false noise. Ordinary incidents notify through the channels attached to the monitor (see Alerts).
A monitor’s incident list appears both at /projects/{id}/incidents and as a timeline at the bottom of the monitor’s detail page. The list is paginated: with many incidents, “Prev / N of M / Next” navigation appears at the bottom. (The recent-checks table on the monitor page is not paginated — it shows the last 50 checks in a scroll container.)
Monitor detail page
Clicking a monitor’s name opens /monitors/{id}: current status, uptime% over 24h/7d/30d, a latency chart, a table of recent checks per region, an incident timeline, and — for HTTPS monitors — the SSL certificate’s expiry. A project’s operators (team members), admins, and owner also get Pause/Resume, Edit, and Delete actions here.
What’s next
- Probes — running a check from another region.
- Public status pages — a public view of service state.
- Maintenance windows — suppressing noise during planned work.
- Alerts — where and how incident notifications are delivered.