Monitors
HTTP, SSL, TCP, DNS and composite checks, their options and defaults.
A monitor describes one thing to check. Every monitor shares a small set of
public fields, and each type adds its own. Names identify a monitor
everywhere — in history rows, incidents, badges, metrics and notifications —
so they must be unique and are expensive to rename.
Shared fields
Unique, non-empty. Used as the history key, the badge path segment, the Prometheus label and the display name.
Secondary line shown under the monitor name on the page.
Public category, for example "Web" or "API". Monitors sharing a group
are rendered together, and the group gets its own derived status.
Defaults to false. A private monitor is still checked and still triggers
notifications and automatic incidents, but is omitted from public
snapshots, badges, metrics and the page.
http
The common case: request a URL and assert the response.
HTTP(S) only.
Defaults to "GET".
Request headers. Values are sent verbatim — keep secrets in environment variables.
Defaults to [200]. Any listed status counts as healthy.
Exact-match response headers. A missing or different value fails the check and names the header in the message.
Substring that must appear in the body. Requesting the body is what makes a "200 that renders an error page" detectable.
Substring that must not appear in the body.
Deep partial match against the parsed JSON body. Nested objects are matched key by key; arrays must be deeply equal.
Defaults to 10000. A timeout is reported as
HTTP timed out after <n>ms.
Defaults to false. When enabled, a first failure is retried once after
softFailMs before the result is recorded as down.
Defaults to 500. Delay before the soft retry.
Defaults to true. Set false to assert the redirect itself, usually with
expectedStatus: [301].
A soft retry that succeeds is still recorded as up, with
…; recovered on soft retry appended to the message. Latency always measures
the whole check, including the retry window, so a soft-failing monitor reports
honestly slow numbers.
ssl
Opens a TLS connection and inspects the peer certificate.
Hostname, also sent as SNI.
Defaults to 443.
Defaults to 14. A certificate expiring sooner fails the check and is
flagged as expiring rather than down.
Defaults to 10000.
The check fails when the certificate chain is not authorized, when the expiry
date cannot be read, or when the remaining lifetime is below
warnBeforeDays. Only the last case is flagged expiring, which is what
turns the alert into an ssl.expiring event instead of monitor.down.
ssl needs node:tls. On Workers the check records
TLS monitoring is unavailable in this runtime. and reports down.
Run certificate checks from a Node or Bun host, or leave them out of a
Workers deployment.
tcp
Opens a socket and treats a successful connection as healthy.
1–65535.
Defaults to 10000.
Like ssl, this needs a native runtime — node:net — and is unavailable on
Cloudflare Workers. Internal hosts are usually paired with private: true so
the hostname never reaches the public page.
dns
Resolves a record through Cloudflare DNS-over-HTTPS, so it works in every runtime including Workers.
Defaults to "A". Any type the DoH resolver accepts, e.g. AAAA, MX,
TXT, CNAME, NS.
Defaults to 10000.
The check fails when the HTTP query fails, when the DNS response status is not
0, or when the answer section is empty.
composite
A composite monitor performs no I/O. It aggregates other monitors from the same check run, which makes it the right tool for "is the product usable", rather than "is this one endpoint reachable".
Names of configured, non-composite monitors. Duplicates are rejected, and an unknown name fails configuration validation.
Defaults to "all".
| Strategy | Healthy when |
|---|---|
all | every component is healthy |
any | at least one component is healthy |
majority | more than half the components are healthy |
A composite reports the highest latency among its components, and its
message states the ratio, for example 2/3 components healthy (strategy: all).
If a component produced no result at all, the composite fails and names it —
a misconfiguration must never look like a healthy aggregate.
Grouping and visibility
- Monitors with the same
groupare published as aMonitorGroupwhose status isoperational,degraded(some failing) oroutage(all failing). - Monitors without a
groupare rendered on their own, after the groups. private: trueremoves a monitor from the public snapshot entirely, so it never appears in/status,/monitors, badges, Prometheus or the page.
Choosing timeouts and intervals
A check run executes every non-composite monitor concurrently, then derives
composites. The slowest monitor therefore bounds the run, not the sum. Keep
timeoutMs comfortably below checks.interval so a stalled endpoint cannot
overlap the next scheduled run.