> ## Documentation Index
> Fetch the complete documentation index at: https://warden.buildlab.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Metrics

> What Warden exposes to a monitoring system, and the six questions those numbers answer.

```
GET /metrics
Authorization: Bearer wc_live_…
```

Prometheus exposition format, on the gateway's own port.

> [!NOTE]
>
> **Operator-authenticated, unlike `/health`.** The numbers name agents, connections, and refusal codes. An open scrape endpoint would tell anyone who can reach the port which agents exist, how often they are refused, and when a human is reviewing a change.

```yaml prometheus.yml theme={null}
scrape_configs:
  - job_name: warden
    metrics_path: /metrics
    authorization:
      type: Bearer
      credentials: wc_live_…      # an operator token with the read capability
    static_configs:
      - targets: ["warden.internal:9470"]
```

## What is exposed

| Metric | Type | Labels |
| - | - | - |
| `warden_operations_total` | counter | connection, agent, class, status |
| `warden_denials_total` | counter | connection, agent, code |
| `warden_empty_suspicious_total` | counter | connection, agent |
| `warden_approvals_total` | counter | connection, reason, verdict |
| `warden_approval_wait_seconds` | histogram | connection, reason |
| `warden_gateway_overhead_seconds` | histogram | connection, class |
| `warden_database_seconds` | histogram | connection, class |
| `warden_debug_sessions_started_total` | counter | connection |
| `warden_breaker_freezes_total` | counter | connection, agent |
| `warden_lease_events_total` | counter | connection, event |
| `warden_webhook_deliveries_total` | counter | hook, event, result |
| `warden_webhook_duration_seconds` | histogram | hook |
| `warden_scrape_errors_total` | counter | source |
| `warden_pending_operations` | gauge | — |
| `warden_debug_sessions_active` | gauge | — |
| `warden_agents_frozen` | gauge | connection |
| `warden_leases_active` | gauge | — |

Gauges are read when you scrape, from the components that own that state, so they cannot drift from it.

## The questions they answer

**Is Warden in my way?**

```promql theme={null}
histogram_quantile(0.99, sum by (le) (rate(warden_gateway_overhead_seconds_bucket[5m])))
```

Overhead is Warden's own time: the whole pipeline minus the database, and minus any wait for a human — waiting for a reviewer is not a cost Warden is imposing. The budget is 5ms. It is recorded whatever the outcome, including refusals: a budget measured only over successes hides the paths where Warden does the most work. `warden_database_seconds` is the engine's share, for when the two need separating.

**Is blocking approval viable?**

```promql theme={null}
sum(rate(warden_approvals_total{reason="approval",verdict="timeout"}[24h]))
  / sum(rate(warden_approvals_total{reason="approval"}[24h]))
```

Expiry rate. **Filter on `reason="approval"`**: Debug Mode pauses share this metric, are far more numerous, and resolve in seconds, so leaving them in the denominator makes the rate read far lower than it is. Above roughly 30% and the answer is no: switch those connections to [async mode](https://warden.buildlab.in/configure/approvals.md), because agents are being blocked on humans who are not answering.

```promql theme={null}
histogram_quantile(0.5, sum by (le) (rate(warden_approval_wait_seconds_bucket[24h])))
```

Median time to a decision — the number to quote when someone asks what review costs.

**What is Warden buying me?**

```promql theme={null}
sum by (code) (increase(warden_denials_total[7d]))
```

Refusals by reason, per week. `unbounded_operation` and `scope_unenforceable` are the interesting ones: those are the operations that would have run against production.

**Is my agent hallucinating?**

```promql theme={null}
sum by (agent) (increase(warden_empty_suspicious_total[24h]))
```

Reads that returned nothing from data that is not empty. A rising line for one agent usually means it is inventing values, and it is worth looking at before a customer is told they have no orders.

**Is the wedge sticky?**

```promql theme={null}
sum(increase(warden_debug_sessions_started_total[7d]))
```

**Is anything on fire right now?**

`warden_scrape_errors_total` above zero means a gauge could not be read — its series will be missing rather than wrong, so alert on the counter, not on the gap. `warden_pending_operations` climbing means reviewers are not keeping up. `warden_agents_frozen` above zero means a circuit breaker tripped and a human has not reinstated the agent.

## Cardinality

Labels are bounded by configuration, not by traffic: agents and connections are declared in `warden.yaml`, classes and statuses are fixed sets, and codes come from [the error taxonomy](https://warden.buildlab.in/api/errors.md). Nothing from a request body becomes a label, so no agent can inflate your metric storage by issuing unusual statements.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.