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:

TypeWhat it checksFields
HTTPAn HTTP(S) request to a URL; success is the response code and, optionally, body contentMethod (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)
TCPWhether a TCP connection to host:port succeedsHost, Port (1–65535)
DNSWhether a name resolves and, optionally, matches an expected valueHostname, Record type (A/AAAA/CNAME/MX/TXT), Expected value (optional)
HeartbeatThe 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 downGrace 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:

ConsensusRuleWhen to use it
“Any region”Down if at least one region is downStrict: any single point of unavailability is already a problem
“Majority of regions”Down if half or more of the decided regions are downA compromise: tolerates a single regional blip
“All regions”Down only if every region is downLenient: 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