Skip to main content
Relay exports Prometheus metrics for traffic, latency, its own overhead, and a few saturation signals. Everything is in the relay namespace, plus the standard Go runtime and process collectors.

Scrape endpoint

Metrics are served at /metrics on the control listener (RELAY_CONTROL_PORT, default 8081) — at the listener root, not under the /api prefix.
Prometheus scrape config

Request flow

The core RED-style metrics (Rate, Errors, Duration), plus the Relay-vs-upstream time split. All are labelled by source — the runner that handled the request: pipeline, proxy, ws, or batch.
relay_overhead_seconds is the metric to watch — it isolates the latency Relay itself adds. The performance SLO lives here: p99 overhead under 10 ms in a live distributed deployment. Its buckets are tuned tight (100 µs → 500 ms) for exactly this question.
relay_overhead_seconds and relay_admission_seconds are only observed when the request actually reached upstream. A request rejected before handoff (auth failure, rate-limited, no healthy key) is counted in relay_requests_total but contributes no overhead/admission sample — there’s no meaningful split to record.

Health & saturation

Leading indicators for the two failures that hurt silently: dropped background records, and provider keys dying off.
relay_provider_keys_down_total is a counter of cooldown transitions, not a gauge of “keys down right now.” Breaker state lives in shared kv, so a per-pod gauge would be inconsistent across the fleet; trip counts, by contrast, sum cleanly. Watch its rate, not its absolute value.

Standard collectors

The default Go and process collectors are registered too, so you also get the usual go_* (goroutines, GC, memory) and process_* (CPU, FDs, resident memory) series without any extra configuration.