This is Part 1 of the Monitoring NATS series. Part 2 covers event-driven monitoring using the NATS system account.
NATS takes a different approach to observability than most distributed systems. Instead of relying on external monitoring probes, sidecars, or heavyweight telemetry pipelines, the nats-server binary includes a built-in HTTP server that exposes real-time telemetry as JSON.
This data reflects the live internal state of the server. There’s no sampling, no asynchronous exporters inside the server, and no continuously running probes competing for CPU or memory. Responses from the monitoring endpoints reflect what the server is doing at that moment.
The tradeoff is intentional: you get accurate, low-overhead telemetry, but you need to understand which endpoints exist, what they report, and how to expose them safely.
/healthz for liveness/varz for server health and runtime metrics/connz for client connection state/routez, /leafz, and /gatewayz for topology/subsz for subscription interest/jsz for JetStream persistenceFor security, the monitoring subsystem is disabled by default. These endpoints expose detailed information about your infrastructure, client behavior, and subject topology.
Once explicitly enabled, the server runs a lightweight HTTP(S) listener that serves JSON responses for each endpoint. Every endpoint is read-only and reflects the current state of the server at request time.
Unlike systems that depend on continuously running monitoring probes, NATS exposes telemetry directly from the server process itself.
You can enable monitoring in three ways:
CLI flag
nats-server -m 8222Configuration file (HTTP)
1http_port: 8222Configuration file (HTTPS – recommended)
1https_port: 82222
3tls {4 cert_file: "/path/to/server.crt"5 key_file: "/path/to/server.key"6}Once enabled, you can access endpoints like:
1https://localhost:8222/varzEach endpoint follows the same pattern: append the endpoint name to the monitoring URL and parse the JSON response.
Important: NATS does not provide authentication or authorization for the monitoring HTTP server. Treat this port as internal-only.
For basic liveness and readiness checks, use /healthz.
200 OK when the server is able to accept connectionsUse /healthz for “is this node alive?”
Use /varz for “is this node healthy and behaving correctly?”
The /varz endpoint provides a high-level snapshot of server state, resource usage, and throughput. It’s the best place to start when diagnosing overall node health.
Memory and CPU
mem reflects memory used by the NATS processcpu reports process CPU usage as observed by the Go runtime
Slow Consumers
slow_consumers increments when the server detects clients that cannot drain outbound data fast enoughUptime
Throughput
in_msgs, out_msgs, in_bytes, out_bytesLimits and Capacity
/varz includes both configured limits and current usage:
max_payloadmax_connectionsmax_subscriptionsWhen limits are reached, new connections or subscriptions are rejected.
The /connz endpoint exposes detailed information about every active client connection. This is your primary tool for identifying misbehaving clients and debugging traffic patterns.
Pending Bytes
Message Counts
msgs_to and msgs_from reveal high-volume producers and consumersIdle Time
On busy servers, always use query parameters:
1?limit=100&offset=02?sort=pending3?subs=14?state=closedRecently closed connections include exit reasons, which is invaluable for diagnosing intermittent failures.
As deployments scale beyond a single node, topology visibility becomes essential.
Shows active routes between cluster nodes.
Key fields:
remote_idpending_sizein_msgs, out_msgsHigh pending sizes may indicate network congestion, slow peers, or asymmetric traffic patterns.
Additional topology endpoints:
/leafz – leaf node connections/gatewayz – inter-cluster gatewaysThese are critical for multi-region and edge deployments.
The /subsz endpoint exposes the internal subscription interest graph used for message routing.
Use cases:
Warning: Output can be very large. In production, prefer targeted CLI queries over full dumps.
If you use JetStream, /jsz becomes a first-class monitoring endpoint.
Reserved Resources
reserved_memreserved_storeStreams
API Errors
1/jsz?accounts=1Provides per-account resource usage for multi-tenant or shared environments.
Monitoring endpoints expose sensitive operational data and must never be public.
Network Isolation (Primary Defense)
TLS
https_port in productionExternal Authentication (If Required)
The NATS Prometheus Exporter is the standard production integration. It:
If you prefer not to expose HTTP monitoring ports on each server, tools like Surveyor collect metrics over the NATS protocol instead, providing a single Prometheus endpoint for your entire cluster. Part 2 of this series covers this approach in detail.
For immediate troubleshooting, nats-top provides a live view of server activity:
nats-top -s https://localhost:8222This is often the fastest way to answer: “What’s happening right now?”
/healthz for liveness checks/varz for capacity and health/connz during incidents/subsz, /routez, /leafz, and /gatewayz for targeted debuggingNATS’ built-in monitoring endpoints give you accurate observability without relying on external monitoring probes. Whether you’re running a single node or a global supercluster, the same primitives apply—the difference is scale and aggregation.
HTTP monitoring endpoints are pull-based: you query them and receive a point-in-time snapshot. This works well for dashboards and trend analysis, but it has limitations. If a client connects and disconnects between scrapes, you may never see it.
In Part 2 of this series, we explore the NATS system account ($SYS)—a push-based, event-driven approach that delivers real-time advisories for connections, disconnections, authentication errors, and more. You’ll also learn how to query the same monitoring data covered here using the NATS protocol instead of HTTP.
The team at Synadia are the creators and maintainers of NATS. If you need help architecting, monitoring, or scaling your deployment, get in touch.
News and content from across the community