# Monitor Metrics

API7 Gateway provides two ways to monitor traffic:

* A built-in **Monitoring** page in the Dashboard for at-a-glance status checks with no extra infrastructure.
* A Prometheus scrape endpoint on the data plane for raw gateway metrics, custom queries, and integration with Prometheus-compatible monitoring.

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

* A [token from the Dashboard](https://docs.api7.ai/api7-gateway/reference/obtain-dashboard-token.md).

## Approach 1: Built-in Monitoring Page[​](#approach-1-built-in-monitoring-page "Direct link to Approach 1: Built-in Monitoring Page")

The Dashboard's **Monitoring** section displays the most critical real-time metrics:

| Metric         | Description                                                   |
| -------------- | ------------------------------------------------------------- |
| **QPS**        | Queries per second, indicating the current load.              |
| **Latency**    | Request processing time (average, p90, p99).                  |
| **Error Rate** | The percentage of requests returning 4xx or 5xx status codes. |
| **Throughput** | Inbound and outbound data volume.                             |

To access this page, sign in to the Dashboard and navigate to **Monitoring**.

## Approach 2: Prometheus Scrape Endpoint[​](#approach-2-prometheus-scrape-endpoint "Direct link to Approach 2: Prometheus Scrape Endpoint")

Enable the [`prometheus`](https://docs.api7.ai/hub/prometheus.md) plugin as a global rule to expose raw metrics at `http://<data-plane>:9091/apisix/prometheus/metrics`. Prometheus can scrape this endpoint directly, or DP Manager can send the same metrics to Prometheus through remote write.

### Step 1: Enable the Prometheus Plugin Globally[​](#step-1-enable-the-prometheus-plugin-globally "Direct link to Step 1: Enable the Prometheus Plugin Globally")

* Admin API
* ADC

```
curl -k "https://localhost:7443/apisix/admin/global_rules/prometheus?gateway_group_id={gateway_group_id}" -X PUT \

  -H "X-API-KEY: ${API_KEY}" \

  -H "Content-Type: application/json" \

  -d '{

    "plugins": {

      "prometheus": {}

    }

  }'
```

adc.yaml

```
global_rules:

  prometheus: {}
```

This command updates global rules only. Services, routes, and consumers stay in place. Global rules absent from the file are removed. Preview the diff:

```
adc diff -f adc.yaml \

  --include-resource-type global_rule
```

Synchronize the reviewed configuration:

```
adc sync -f adc.yaml \

  --include-resource-type global_rule
```

### Step 2: Verify the Endpoint[​](#step-2-verify-the-endpoint "Direct link to Step 2: Verify the Endpoint")

Send a request through any route to generate metrics, then scrape the Prometheus endpoint on the data plane:

```
curl "http://127.0.0.1:9091/apisix/prometheus/metrics"
```

You should see Prometheus-formatted metrics including counters, gauges, and histograms emitted by the gateway.

The metrics listener binds to `127.0.0.1` by default. Publishing port `9091` does not make that loopback-only listener reachable from outside a container or pod.

For a gateway configured with `config.yaml`, set the listener to an address that your monitoring network can reach:

config.yaml

```
plugin_attr:

  prometheus:

    export_addr:

      ip: 0.0.0.0

      port: 9091
```

Restart the gateway, then publish or expose the port.

For a gateway deployed with the API7 Gateway Helm chart and Prometheus Operator, enable the chart's ServiceMonitor integration. This binds the listener to `0.0.0.0`, exposes port `9091` through the gateway Service, and creates a ServiceMonitor:

values.yaml

```
serviceMonitor:

  enabled: true
```

This option requires the ServiceMonitor custom resource definition. To change the listener address without creating a ServiceMonitor, configure `pluginAttrs.prometheus.export_addr`. You must also expose port `9091` with a Kubernetes Service or request the pod IPs directly. Changing `pluginAttrs` alone does not add a Service port.

If you do not want to expose the listener, use the [DP Manager remote-write path](https://docs.api7.ai/api7-gateway/observability/external-prometheus.md).

caution

The metrics endpoint is unauthenticated. Restrict it to the monitoring network instead of exposing it with proxy traffic.

### Step 3: Configure Prometheus to Scrape[​](#step-3-configure-prometheus-to-scrape "Direct link to Step 3: Configure Prometheus to Scrape")

If you enabled the Helm chart's ServiceMonitor integration, Prometheus Operator configures the scrape for you. Otherwise, add each data plane to your Prometheus `scrape_configs`:

prometheus.yml

```
scrape_configs:

  - job_name: api7-gateway

    metrics_path: /apisix/prometheus/metrics

    static_configs:

      - targets:

          - <data-plane-host>:9091
```

To send metrics without exposing port `9091` outside the data plane, use the [DP Manager remote-write path](https://docs.api7.ai/api7-gateway/observability/external-prometheus.md) instead.

Known limitation: duplicate metric family

Currently released gateway versions emit the `apisix_nginx_metric_errors_total` family twice, each time with its own `HELP`, `TYPE`, and sample lines. Prometheus keeps the target up, ingests all metric families, and drops the repeated sample. Prometheus 2.52.0 and later logs a warning: `Error on ingesting samples with different value but same timestamp`. Earlier versions ignore the repeated series silently.

Strict text-format checks reject the whole payload. For example, `promtool check metrics` reports `second HELP line for metric name "apisix_nginx_metric_errors_total"`.

## Key Metrics[​](#key-metrics "Direct link to Key Metrics")

When building dashboards or alerts, focus on these metrics emitted by the `prometheus` plugin:

* `apisix_http_status` — counter of responses by status code (label `code`).
* `apisix_http_latency` — histogram of request latency (label `type` distinguishes `request`, `upstream`, and `apisix`).
* `apisix_bandwidth` — counter of bytes sent and received (label `type`).
* `apisix_nginx_http_current_connections` — gauge of active connections (label `state`).

For the data-plane metric families and their built-in labels, see [Data Plane Metrics Reference](https://docs.api7.ai/api7-gateway/observability/metrics-reference.md). For plugin configuration and label tuning, see [`prometheus`](https://docs.api7.ai/hub/prometheus.md).

## Additional Resources[​](#additional-resources "Direct link to Additional Resources")

* [Configure Alerts](https://docs.api7.ai/api7-gateway/observability/alerts.md) based on metric thresholds.
* [Review the data-plane metrics reference](https://docs.api7.ai/api7-gateway/observability/metrics-reference.md) before writing PromQL queries.
* [Configure Distributed Tracing](https://docs.api7.ai/api7-gateway/observability/tracing.md) to investigate latency spikes surfaced in the metrics.
* [Configure Centralized Logging](https://docs.api7.ai/api7-gateway/observability/logging.md) to correlate metric anomalies with log entries.
