---
title: "Metrics list"
url: "/reference/observability/metrics-list/"
kind: "reference"
summary: "Every metric Arion emits, by family, with types and labels, and where to scrape them."
---

> Arion site index: [/llms.txt](/llms.txt)

# Metrics list

Every metric Arion emits, by family, with types and labels, and where to scrape them.

This page lists the metrics Arion emits when built with the `metrics` feature, grouped by family.

Metrics are exposed three ways: in Prometheus text format at the admin endpoint `/stats/prometheus` (requires the `prometheus` build feature and the [admin listener](@/reference/observability/admin-api.md)), in Envoy-style text at admin `/stats`, and pushed over OTLP when `envoy_bootstrap.stats_sinks` and `stats_flush_interval` are configured. Prometheus names join the family and metric name with an underscore (`http_downstream_rq_total`); the `/stats` output prints `family.<label values>.name: value`. Histograms use millisecond buckets 5, 10, 50, 100, 500, 1000, 5000, 10000, +Inf (bytes buckets for `mcp_tool_response_bytes`) and export `_bucket`, `_sum` and `_count` series in Prometheus format. Any built-in metric can be renamed with the top-level `metrics.rename` map; see [metrics](@/docs/observe/metrics.md).

## Listener (`listeners_*`)

| Name | Type | Labels | Description |
|---|---|---|---|
| `downstream_cx_total` | counter | `listener` | Connections accepted. |
| `downstream_cx_destroy` | counter | `listener` | Connections destroyed. |
| `downstream_cx_active` | gauge | `listener` | Active connections. |
| `downstream_cx_length_ms` | histogram | `listener` | Connection lifetime in milliseconds. |
| `no_filter_chain_match` | counter | `listener` | Connections that matched no filter chain. |

## HTTP (`http_*`)

Emitted by the HTTP connection manager.

| Name | Type | Labels | Description |
|---|---|---|---|
| `downstream_cx_total` | counter | `listener` | HTTP connections. |
| `downstream_cx_ssl_total` | counter | `listener` | HTTP connections over TLS. |
| `downstream_cx_ssl_active` | gauge | `listener` | Active TLS HTTP connections. |
| `downstream_cx_destroy` | counter | `listener` | HTTP connections destroyed. |
| `downstream_cx_active` | gauge | `listener` | Active HTTP connections. |
| `downstream_cx_length_ms` | histogram | `listener` | HTTP connection lifetime in milliseconds. |
| `downstream_cx_rx_bytes_total` | counter | `listener` | Bytes received on HTTP connections. |
| `downstream_cx_tx_bytes_total` | counter | `listener` | Bytes sent on HTTP connections. |
| `downstream_rq_total` | counter | `listener` | Requests received. |
| `downstream_rq_active` | gauge | `listener` | Requests in flight. |
| `downstream_rq_1xx` … `downstream_rq_5xx` | counter | `listener` | Responses by status class (five metrics). |
| `downstream_cx_ws_upgrades_total` | counter | `listener` | Successful WebSocket upgrades. |
| `downstream_cx_ws_upgrades_active` | gauge | `listener` | Active upgraded connections. |
| `downstream_rq_ws_on_non_ws_route` | counter | `listener` | Upgrade requests rejected by non-upgrade routes. |

## TCP proxy (`tcp_*`)

| Name | Type | Labels | Description |
|---|---|---|---|
| `downstream_cx_total` | counter | `listener` | TCP connections. |
| `downstream_cx_destroy` | counter | `listener` | TCP connections destroyed. |
| `downstream_cx_active` | gauge | `listener` | Active TCP connections. |
| `downstream_cx_length_ms` | histogram | `listener` | TCP connection lifetime in milliseconds. |
| `cx_rx_bytes_received` | counter | `listener` | Bytes received on proxied TCP connections. |
| `cx_tx_bytes_sent` | counter | `listener` | Bytes sent on proxied TCP connections. |

## TLS (`tls_*`)

| Name | Type | Labels | Description |
|---|---|---|---|
| `handshake` | counter | `listener` | Successful TLS handshakes. |

## Cluster (`cluster_*`)

| Name | Type | Labels | Description |
|---|---|---|---|
| `upstream_rq_total` | counter | `cluster` | Upstream requests. |
| `upstream_rq_active` | gauge | `cluster` | Upstream requests in flight. |
| `upstream_rq_time` | histogram | `cluster` | Upstream request time in milliseconds. |
| `upstream_rq_timeout` | counter | `cluster` | Requests that hit the route timeout. |
| `upstream_rq_per_try_timeout` | counter | `cluster` | Attempts that hit the per-try timeout. |
| `upstream_rq_retry` | counter | `cluster` | Request retries. |
| `upstream_cx_total` | counter | `cluster` | Upstream connections. |
| `upstream_client_exec_total` | counter | `cluster` | HTTP client executor spawns (connection dispatchers and HTTP/1 idle waiters). |
| `upstream_cx_active` | gauge | `cluster` | Active upstream connections. |
| `upstream_cx_destroy` | counter | `cluster` | Upstream connections destroyed. |
| `upstream_cx_idle_timeout` | counter | `cluster` | Upstream connections closed by idle timeout. |
| `upstream_cx_connect_fail` | counter | `cluster` | Failed upstream connection attempts. |
| `upstream_cx_connect_timeout` | counter | `cluster` | Upstream connection attempts that timed out. |
| `upstream_cx_rx_bytes_total` | counter | `cluster` | Bytes received from upstreams. |
| `upstream_cx_tx_bytes_total` | counter | `cluster` | Bytes sent to upstreams. |
| `upstream_cx_overflow` | counter | `cluster` | Connections rejected by the circuit breaker. |
| `upstream_rq_overflow` | counter | `cluster` | Requests rejected by the circuit breaker. |
| `upstream_rq_retry_overflow` | counter | `cluster` | Retries rejected by the circuit breaker. |

## Server (`server_*`)

Unlabelled gauges, refreshed when the stats endpoints are read.

| Name | Type | Labels | Description |
|---|---|---|---|
| `uptime` | gauge | — | Server uptime in seconds. |
| `concurrency` | gauge | — | Number of worker threads. |
| `memory_heap_size` | gauge | — | Reserved heap size in bytes (requires the `jemalloc` build feature; falls back to physical memory). |
| `memory_physical_size` | gauge | — | Physical memory of the process in bytes. |
| `memory_allocated` | gauge | — | Allocated heap bytes (requires `jemalloc`; falls back to physical memory). |

## Filter (`filter_*`)

The `result` label is `ok`, `rate_limited` or `not_applicable`; `filter` is the filter's `stat_prefix`.

| Name | Type | Labels | Description |
|---|---|---|---|
| `connection_rate_limit` | counter | `filter`, `result` | Listener local rate limit decisions. |
| `local_rate_limit` | counter | `filter`, `result` | HTTP local rate limit decisions. |
| `user_rate_limit` | counter | `filter`, `user`, `result` | User rate limit decisions. |

## User (`user_*`)

Per-caller metrics, partitioned by the identity configured in `metrics.user_key` (a request header or the TLS SNI). The label name is the configured `attribute_name` — `user` in the examples below.

| Name | Type | Labels | Description |
|---|---|---|---|
| `invocations` | counter | `user` | API calls. |
| `throttles` | counter | `user` | API calls that were rate limited. |
| `system_errors` | counter | `user` | API calls that ended in a server-side error. |
| `user_errors` | counter | `user` | API calls that ended in a client-side error. |
| `total_errors` | counter | `user` | API calls that ended in any error. |
| `latency` | histogram | `user` | API call latency in milliseconds. |
| `upstream_rq_time` | histogram | `user` | Upstream request time in milliseconds. |
| `bytes_tx` | counter | `user`, `listener` | Bytes sent to the caller. |
| `bytes_rx` | counter | `user`, `listener` | Bytes received from the caller. |
| `inbound_streaming_bytes_processed` | counter | `user` | Inbound WebSocket bytes. |
| `outbound_streaming_bytes_processed` | counter | `user` | Outbound WebSocket bytes. |
| `connections` | counter | `user` | Connections established. |
| `connections_active` | gauge | `user` | Active connections. |
| `http_1xx_response` … `http_5xx_response` | counter | `user` | Responses by status class (five metrics). |
| `http_404_response` | counter | `user` | 404 responses. |
| `http_502_response` | counter | `user` | 502 responses. |
| `http_504_response` | counter | `user` | 504 responses. |

## MCP gateway (`mcp_*`)

Emitted by the [MCP gateway filter](@/reference/filters/http/mcp-gateway.md) and exported through the OTLP pipeline; they are not listed by the admin `/stats` endpoints. Tools are identified by their qualified name, `namespace.name`. In [code mode](@/docs/mcp-gateway/code-mode.md), every tool call a script makes is counted under that tool, the same as a direct `tools/call`.

| Name | Type | Labels | Description |
|---|---|---|---|
| `tool_rq_total` | counter | `mcp.tool.name`, `mcp.backend`, `mcp.upstream` | Tool invocations dispatched to a backend. |
| `tool_rq_failures_total` | counter | `mcp.tool.name`, `mcp.backend`, `mcp.upstream`, `mcp.error.code` | Tool invocations that produced a tool error. |
| `tool_rq_time` | histogram | `mcp.tool.name`, `mcp.backend`, `mcp.upstream` | Tool invocation time in milliseconds. |
| `tool_response_bytes` | histogram | `mcp.tool.name`, `mcp.backend`, `mcp.upstream` | Upstream tool response payload size in bytes. |
| `embedding_failures_total` | counter | — | Failed embeddings requests for tool search, counted once per failed batch. |

## Custom metrics (`custom_*`)

User-defined counters, histograms and gauges declared under the top-level `metrics.custom_metrics` map extract values from request or response headers at six hook points and appear alongside the built-in families. Their names and labels are whatever the configuration declares; see [metrics](@/docs/observe/metrics.md) for the configuration.
