SrvPulse

Docs / Collector topology

Collector topology

Two hops by design: agent to collector inside the region, collector to aggregation across it.

Agentsregion-local
→
api.srvpulse.netru-central collector
→
connect.api.srvpulse.neteu-west aggregation

Hop 1 — agent to collector

Agents reach the collector on 443 over gRPC, falling back to WebSocket. Both carry the same protobuf payloads and both authenticate with the client certificate issued at enrolment.

 gRPCWebSocket
ALPNh2http/1.1
Service / pathsrvpulse.collector.v1.CollectorService/static/bundle/c2f91a7e/live
Streamsmultiplexed, one connectionone connection per stream
Compressiongzippermessage-deflate
Keepaliveh2 PING, 45sping frame, 30s
Behind middleboxescan be truncatedmore tolerant

The WebSocket endpoint is an upgrade, not a browsable resource — a request without an Upgrade header gets 404:

GET wss://api.srvpulse.net/static/bundle/c2f91a7e/live
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: srvpulse.v1

Hop 2 — collector to aggregation

Every agent in a region is multiplexed into one long-lived mutually authenticated channel from the collector to its aggregation endpoint. The channel is established by the collector outbound; aggregation never dials back.

collector:  api.srvpulse.net        (ru-central)
upstream:   connect.api.srvpulse.net:443
auth:       mTLS, collector certificate, rotated every 90 days
framing:    length-prefixed protobuf over a single stream
batching:   250 ms or 64 KiB, whichever first
spool:      /var/lib/srvpulse/upstream  (replayed oldest-first)

Aggregation endpoints accept connections only from enrolled collectors; their address ranges are pinned at enrolment. This is why pointing an agent straight at connect.api.srvpulse.net fails with PERMISSION_DENIED — it is not an agent-facing endpoint.

Backpressure and ordering

  • Samples are idempotent on (host, metric, window_start), so a replay after reconnect never duplicates.
  • Ordering is not guaranteed across hosts and is not needed — every sample is self-timestamped at the agent.
  • Replay is rate-limited to a quarter of the negotiated ceiling, so recovery never starves live data.
  • On RESOURCE_EXHAUSTED the collector honours retry-after and keeps spooling until its disk budget is reached.

Link-check payload

Every collector and aggregation endpoint serves a fixed 2 MiB incompressible payload used by srvpulse-agent linkcheck and by our own path monitoring:

GET https://api.srvpulse.net/static/probe/linkcheck-9c42.bin
→ 200, content-length: 2097152, cache-control: no-store

It carries no workspace data and is not part of the data plane. Its only purpose is to tell a slow path from a truncated one.