Observability
NetBird services emit runtime metrics via OpenTelemetry and expose them in Prometheus exposition format (with OpenMetrics 1.0.0 support). You can scrape these endpoints to monitor traffic, latency, peer activity, and the internal health of each service, and to render the Grafana dashboards NetBird ships.
This section documents what each service records, the default listening endpoint, and how to change it.
Service endpoints
Every server-side component exposes a /metrics HTTP endpoint. By default, Management, Signal, Relay, and Combined listen on port 9090; Proxy listens on port 8080.
| Service | Default endpoint | How to change |
|---|---|---|
| Management | http://0.0.0.0:9090/metrics | --metrics-port flag |
| Signal | http://0.0.0.0:9090/metrics | --metrics-port flag |
| Relay | http://0.0.0.0:9090/metrics | --metrics-port flag |
| Proxy | http://localhost:8080/metrics | --health-addr flag / NB_PROXY_HEALTH_ADDRESS |
| Combined | http://0.0.0.0:9090/metrics | server.metricsPort in config.yaml |
The proxy exposes /metrics on the same HTTP server as its health probes; there is no separate metrics port.
Combined deployments
In the combined container (the default for new installations via getting-started.sh), Management, Signal, and Relay all share one metrics server and one /metrics endpoint. The port is set with server.metricsPort in config.yaml (default 9090) — see Combined.
Multi-container deployments
In the older multi-container setup, each service runs its own metrics server. To avoid port collisions when colocating services on a single host, override --metrics-port per container, for example:
netbird-mgmt --metrics-port 9090
netbird-signal --metrics-port 9091
netbird-relay --metrics-port 9092
Exposition format
All endpoints return Prometheus text format with OpenMetrics support enabled:
curl http://localhost:9090/metrics
Naming conventions
NetBird services register metrics with OpenTelemetry instrument names (using dots as separators, e.g. management.grpc.sync.request.counter). The Prometheus exporter rewrites them on the way out:
- Dots become underscores:
management.grpc.sync.request.counter→management_grpc_sync_request_counter. - Counters get a
_totalsuffix unless the instrument name already ends in_total. Somanagement.grpc.sync.request.counter→management_grpc_sync_request_counter_total, whileregistrations_totalstaysregistrations_total. - UpDownCounters and ObservableGauges are emitted as Prometheus
gaugetypes. The name is unchanged (e.g.proxy_domains_count,relay_peers_active). - Histograms expand to three series —
<name>_bucket,<name>_sum,<name>_count. When the instrument was registered with a unit (milliseconds,microseconds,bytes, …), that unit is appended to the base name unless the name already ends in it. Soproxy.peer.add.duration.mswith unitmillisecondsbecomesproxy_peer_add_duration_ms_milliseconds_bucket, butrelay_peer_authentication_time_milliseconds(no unit registered) staysrelay_peer_authentication_time_milliseconds_bucket.
Service prefixes are baked into the OTel instrument names themselves:
- Management metrics start with
management_*. - Relay metrics start with
relay_*. - Proxy metrics start with
proxy_*. - Signal metrics are unprefixed when Signal runs standalone (
active_peers,messages_forwarded_total, …). In the combined container they are emitted with asignal_prefix (signal_active_peers,signal_messages_forwarded_total, …) so they don't collide with the other services on the shared/metricsendpoint.
The metric tables on the per-service pages show the on-the-wire Prometheus names, so you can copy them straight into a PromQL query.
You can scrape them with a standard Prometheus scrape_config:
scrape_configs:
- job_name: 'netbird-management'
static_configs:
- targets: ['management.example.com:9090']
- job_name: 'netbird-signal'
static_configs:
- targets: ['signal.example.com:9090']
- job_name: 'netbird-relay'
static_configs:
- targets: ['relay.example.com:9090']
- job_name: 'netbird-proxy'
static_configs:
- targets: ['proxy.example.com:8080']
Network exposure
Most metrics endpoints listen on all interfaces (0.0.0.0) and have no authentication; the Proxy endpoint listens on localhost by default. Restrict access at the firewall, reverse proxy, or service-mesh layer so that only your Prometheus scraper and operators can reach them.
Grafana dashboards
NetBird ships ready-to-use Grafana dashboards for Management, Signal, and Relay. See Dashboards for download links and required dashboard variables.

