State Synchronization Setup (NATS + JetStream)
This guide walks you through enabling global state synchronization for health and membership across multiple gslbd instances using NATS with JetStream.
Overview
Each node publishes local health and heartbeats to NATS subjects and KV buckets.
Health state changes (healthy→unhealthy or unhealthy→healthy) are pushed immediately to NATS peers — peer convergence latency is under 200 ms regardless of
checkInterval. A 30 s catchup ticker republishes the full snapshot in the background to recover from any missed signals.Each node subscribes to the cluster subjects and KV snapshots to maintain a global view (
GlobalHealthView).The load balancer uses a composite provider to merge local and global health according to policy.
When to enable
You run multiple GSLB nodes across regions and want them to share health state.
You want quorum-based decisions or fast propagation of health changes.
Prerequisites
NATS 2.x with JetStream enabled.
TLS/mTLS credentials for clients (recommended).
A cluster ID configured in
gslbd.
Recommended topology (super-cluster)
3+ NATS servers per region (odd number for availability).
Connect regions via NATS gateways to form a super-cluster.
Enable JetStream in each cluster; optionally set a JetStream domain (e.g.,
gslb).
Minimal NATS server (single region) example
# nats-server.conf (excerpt)jetstream: { domain: gslb}server_name: n1port: 4222cluster: { name: gslb port: 6222}# TLS, accounts, and gateways omitted for brevity; see NATS docs
Configure gslbd Add to /etc/gslb/config.yaml:
cluster: id: "prod-global" state: healthPolicy: "prefer-local" # or global-any-healthy | global-quorum quorumMinPercent: 51 # used for global-quorum heartbeatInterval: "10s" heartbeatTTL: "30s" nats: servers: ["nats://n1.example.com:4222","nats://n2.example.com:4222","nats://n3.example.com:4222"] tls: caFile: "/etc/gslb/pki/ca.crt" certFile: "/etc/gslb/pki/client.crt" keyFile: "/etc/gslb/pki/client.key" jetStream: domain: "gslb"
!!! note "NATS is ephemeral-only" State sync over NATS covers health and membership only — ephemeral, TTL'd data. Configuration and data-plane objects are not synced over NATS: config flows from git via GitOps self-restart, and pools/members/services/users are replicated by the rqlite datastore (Raft). The old JetStream config-sync (enableConfigSync, NEXUS_CFG) has been removed. See State Sync reference.
Policies explained
local-or-global-fallback (default): use local health, falling back to the global view.
prefer-local: local result is authoritative; global used mainly for hints.
local-only: ignore global state (useful during incidents or testing).
global-any-healthy: consider healthy if any site reports healthy.
global-quorum: healthy only if a percent of active members report healthy within staleness TTL.
How quorum works
Each node publishes periodic heartbeats.
Active membership = nodes whose latest heartbeat is within
heartbeatTTL.For an endpoint, only reports from active members within
heartbeatTTLare counted.quorumMinPercentcomputes healthy threshold:healthy*100/total >= quorumMinPercent.
Verifying connectivity and state
Metrics to watch:
gslbd_state_nats_connected(1 when connected)gslbd_state_active_membersgslbd_state_nats_{published,received}_total{type}gslbd_state_kv_{put,get}_total{bucket,result}gslbd_state_merge_lag_ms— histogram of NATS transit latency from publish to peer receipt; p95 > 500 ms indicates network issues between nodesgslbd_health_failover_detection_seconds{direction}— Layer 1 detection latency per state change on this node;direction="down"is healthy→unhealthy
When Configuration Sync is enabled, logs will include messages like:
config snapshot loadedandconfig event: cluster=... version=....Logs will show connect errors or KV bucket creation errors.
Failure modes
If NATS is unreachable:
gslbdcontinues with local health only (policyprefer-local).If clocks skew: events include timestamps; quorum logic tolerates within TTL but keep NTP enabled.
If membership is zero: no quorum can be established; provider falls back to local (for
global-quorum).
Security
Use mTLS for client/server auth or NATS accounts/JWT with TLS.
Restrict subjects and KV permissions to the cluster namespace (e.g.,
gslb.<cluster>.*).Rotate client certs periodically; see Security Guide.