Skip to content

Gateway heartbeat

Every gateway maintains a persistent WebSocket to the cloud and sends a heartbeat message on a fixed cadence. The cloud marks a gateway offline when the heartbeat stops arriving.

Cadence and timeouts

Source of truth: gateway/internal/cloud/client.go (gateway side) and cloud/internal/devices/gateway_ws.go (cloud side).

ParameterValueConfigurable viaNotes
Heartbeat interval (gateway -> cloud)30 sheartbeat_interval_sec in gateway configCadence at which the gateway sends a heartbeat WebSocket message.
WebSocket ping interval (cloud -> gateway)30 sPingInterval in GatewayWSHubConfigKeep-alive ping from the cloud.
WebSocket pong timeout10 sPongTimeout in GatewayWSHubConfigIf no pong within 10 s after a ping, the cloud tears down the connection.
Write timeout10 sWriteTimeoutTimeout for a single WebSocket write on either side.
Offline threshold90 sgwOfflineTimeout (cloud)If the cloud sees no heartbeat for 90 s, the gateway status transitions to offline.
Offline check interval15 sgwOfflineCheckInt (cloud)How often the cloud sweeps connected gateways for expired heartbeats.
Command timeout30 sgwCommandTimeoutCloud-to-gateway commands fail if no response arrives in 30 s.
Reconnect backoff (max)operator-configuredreconnect_max_backoff_sec in gateway configCap on exponential backoff after a disconnect.

Heartbeat payload fields

Sent by the gateway to the cloud as {"type":"heartbeat","data":<HeartbeatData>} on the interval above.

FieldTypeDescription
cpu_percentfloatCPU utilisation sampled at heartbeat time.
memory_mbintegerResident memory in MB.
versionstringGateway binary version.
timestampISO-8601 timestampTime the heartbeat was sampled (UTC).
camera_recording_statusobjectMap of camera_id -> state for cameras currently recording. Omitted when empty.
network_throughputobjectBytes in/out delta since the previous heartbeat. Omitted when unavailable.

B-10 (audit 2026-05-23): cameras_online and cameras_total were removed from the payload — the cloud never parsed them. The fleet camera-online count surfaced in the dashboard is computed from the cameras.status DB column directly. The cloud parser still tolerates the legacy fields in inbound bodies so older gateway binaries can roll forward without a coordinated cut-over.

Network throughput sub-object

FieldTypeDescription
bytes_inuint64Bytes received on the primary interface since the last heartbeat.
bytes_outuint64Bytes transmitted on the primary interface since the last heartbeat.
measured_atISO-8601 timestampTime the throughput sample ended.

Status transitions

FromToTrigger
onlineofflineNo heartbeat received for 90 s.
offlineonlineAny heartbeat or WebSocket reconnect.
offline or onlinedisabledAdmin disables the gateway (not automatic).
disabledonlineAdmin re-enables and a heartbeat arrives.