# Metrics Reference

This document lists the Prometheus metrics currently exported by the proxy metrics endpoint.

Metrics are exported only when metrics are enabled in configuration. All metric names use the `proxy_` prefix.

## Common Labels

Most request, CQL, MySQL, and connection metrics include these labels:

| Label | Meaning |
| --- | --- |
| `KeyspaceName` | Resolved keyspace name for the request/user when available. Falls back to `unknown`. |
| `ClusterId` | Resolved cluster id for the keyspace when available. Falls back to `-1`. |

Pool and prepared statement cache metrics also include:

| Label | Meaning |
| --- | --- |
| `tenant` | Tenant id associated with the pool/cache snapshot. |
| `user` | User associated with the pool/cache snapshot. |

Histogram metrics expose the standard Prometheus series:

- `<metric>_bucket`
- `<metric>_sum`
- `<metric>_count`

## Request Metrics

### `proxy_request_total`

Type: counter

Labels:

| Label | Values |
| --- | --- |
| `opcode` | Native protocol opcode label, for example `QUERY`, `PREPARE`, `EXECUTE`, `BATCH`, `OPTIONS`. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Total requests by native protocol opcode.

Example:

```promql
sum by (opcode) (rate(proxy_request_total[1m]))
```

### `proxy_request_completed_total`

Type: counter

Labels:

| Label | Values |
| --- | --- |
| `opcode` | Native protocol opcode label. |
| `op_type` | CQL operation type or request operation type, for example `select`, `insert`, `update`, `delete`, `batch`, `ddl_table`, `ddl_user`, `OPTIONS`. |
| `status` | `ok`, `error`. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Completed requests by opcode, operation type, and status.

Example:

```promql
sum by (op_type, status) (rate(proxy_request_completed_total[1m]))
```

### `proxy_request_duration_seconds`

Type: histogram

Labels:

| Label | Values |
| --- | --- |
| `opcode` | Native protocol opcode label. |
| `op_type` | CQL operation type or request operation type. |
| `status` | `ok`, `error`. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: End-to-end request latency by opcode, operation type, and status.

Example:

```promql
histogram_quantile(
  0.99,
  sum by (le, op_type) (rate(proxy_request_duration_seconds_bucket[5m]))
)
```

### `proxy_request_in_flight`

Type: gauge

Labels:

| Label | Values |
| --- | --- |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Current number of in-flight requests.

Example:

```promql
sum by (KeyspaceName) (proxy_request_in_flight)
```

### `proxy_request_stage_seconds`

Type: histogram

Labels:

| Label | Values |
| --- | --- |
| `stage` | Request processing stage. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Latency per request stage.

Supported `stage` values:

| Stage | Meaning |
| --- | --- |
| `frame_read` | Reading the request frame. |
| `queue_wait` | Waiting in request queue. |
| `handler` | Request handler execution. |
| `batch_parse` | Batch parse work. |
| `batch_decode` | Batch parameter decode work. |
| `batch_merge_plan` | Batch merge planning. |
| `batch_execute_wait` | Batch execution wait. |
| `schema_sync` | Schema sync work. |
| `schema_cache_refresh` | Schema cache refresh. |
| `cql_meta_cache_refresh` | CQL metadata cache refresh. |
| `mysql_pool_wait` | Waiting for MySQL pool connection. |
| `mysql_query` | MySQL query execution. |
| `result_encode` | Result encoding. |
| `write_lock_wait` | Waiting for response write lock. |
| `write_flush` | Response write/flush. |
| `total` | Total request time when recorded. |

Example:

```promql
histogram_quantile(
  0.95,
  sum by (le, stage) (rate(proxy_request_stage_seconds_bucket[5m]))
)
```

## CQL Metrics

### `proxy_cql_query_total`

Type: counter

Labels:

| Label | Values |
| --- | --- |
| `query_type` | CQL query type. |
| `status` | `ok`, `error`. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Total CQL queries by query type and status.

Known `query_type` values include:

| Query type | Meaning |
| --- | --- |
| `select` | `SELECT` statement. |
| `insert` | `INSERT` statement. |
| `update` | `UPDATE` statement. |
| `delete` | `DELETE` statement. |
| `batch` | `BEGIN BATCH ... APPLY BATCH`. |
| `use` | `USE` statement. |
| `describe` | `DESCRIBE` statement. |
| `ddl_keyspace` | Keyspace DDL. |
| `ddl_table` | Table DDL. |
| `ddl_type` | Type DDL. |
| `ddl_index` | Index DDL. |
| `ddl_view` | Materialized view DDL. |
| `ddl_trigger` | Trigger DDL. |
| `ddl_function` | Function DDL. |
| `ddl_aggregate` | Aggregate DDL. |
| `ddl_user` | User/permission DDL. |
| `truncate` | `TRUNCATE` statement. |
| `other` | Parsed statement that does not match a known category. |
| `unknown` | Query type could not be determined. |

Example:

```promql
sum by (query_type, status) (rate(proxy_cql_query_total[1m]))
```

### `proxy_cql_query_duration_seconds`

Type: histogram

Labels:

| Label | Values |
| --- | --- |
| `query_type` | CQL query type. |
| `status` | `ok`, `error`. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: End-to-end CQL query latency by query type and status.

Example:

```promql
histogram_quantile(
  0.95,
  sum by (le, query_type) (rate(proxy_cql_query_duration_seconds_bucket[5m]))
)
```

### `proxy_cql_write_rows_total`

Type: counter

Labels:

| Label | Values |
| --- | --- |
| `operation_type` | `insert`, `update`, `batch`. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Total requested logical rows written by CQL operation type. For `insert`, the metric counts CQL rows in the request instead of the backend affected-row value, so an upsert that updates one existing row is counted as one CQL row. For `update`, the metric follows the requested write row count where available, otherwise the affected row count. For `batch`, it counts rows from the original batch request before primary-key merge/fold planning, so folded statements still contribute their original requested row count. Use `rate()` to derive rows per second.

Examples:

```promql
sum by (operation_type) (rate(proxy_cql_write_rows_total[1m]))
```

```promql
quantile_over_time(
  0.8,
  (
    sum by (operation_type) (rate(proxy_cql_write_rows_total[1m]))
  )[1d:1m]
)
```

### `proxy_cql_disconnection_total`

Type: counter

Labels:

| Label | Values |
| --- | --- |
| `scope` | Currently `all`. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Total CQL client disconnections by scope.

Example:

```promql
sum by (KeyspaceName) (rate(proxy_cql_disconnection_total[5m]))
```

### `proxy_cql_connection_count`

Type: gauge

Labels:

| Label | Values |
| --- | --- |
| `scope` | Connection scope, for example `all` or `active` depending on the provider snapshot. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Current number of CQL client connections by scope.

Example:

```promql
sum by (scope, KeyspaceName) (proxy_cql_connection_count)
```

## MySQL Operation Metrics

### `proxy_mysql_operation_total`

Type: counter

Labels:

| Label | Values |
| --- | --- |
| `operation` | MySQL operation label. |
| `status` | `ok`, `error`. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Total MySQL operations by operation and status.

Known `operation` values:

| Operation | Meaning |
| --- | --- |
| `pool_wait` | Waiting for a pooled MySQL connection. |
| `prepare` | Preparing a MySQL statement. |
| `begin_tx` | Beginning a transaction. |
| `query_read` | Read query execution. |
| `query_write` | Write query execution. |
| `exec_write` | Write execution via `Exec`. |

Example:

```promql
sum by (operation, status) (rate(proxy_mysql_operation_total[1m]))
```

### `proxy_mysql_operation_seconds`

Type: histogram

Labels:

| Label | Values |
| --- | --- |
| `operation` | MySQL operation label. |
| `status` | `ok`, `error`. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: MySQL operation latency by operation and status.

Example:

```promql
histogram_quantile(
  0.99,
  sum by (le, operation) (rate(proxy_mysql_operation_seconds_bucket[5m]))
)
```

### `proxy_mysql_error_total`

Type: counter

Labels:

| Label | Values |
| --- | --- |
| `operation` | MySQL operation label. |
| `error_type` | MySQL error type. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Total MySQL errors by operation and error type.

Known `error_type` values:

| Error type | Meaning |
| --- | --- |
| `timeout` | Timeout error. |
| `connection` | Connection error. |
| `driver` | Driver error. |
| `other` | Other error. |

Example:

```promql
sum by (operation, error_type) (rate(proxy_mysql_error_total[5m]))
```

## MySQL Pool Metrics

### `proxy_mysql_pool_open`

Type: gauge

Labels: `tenant`, `user`, `KeyspaceName`, `ClusterId`

Description: Number of open connections in the MySQL pool.

### `proxy_mysql_pool_in_use`

Type: gauge

Labels: `tenant`, `user`, `KeyspaceName`, `ClusterId`

Description: Number of in-use connections in the MySQL pool.

### `proxy_mysql_pool_wait_total`

Type: gauge

Labels: `tenant`, `user`, `KeyspaceName`, `ClusterId`

Description: Total count of MySQL pool waits as reported by the pool stats snapshot.

### `proxy_mysql_pool_wait_seconds_total`

Type: gauge

Labels: `tenant`, `user`, `KeyspaceName`, `ClusterId`

Description: Total time spent waiting for MySQL pool connections, in seconds, as reported by the pool stats snapshot.

Examples:

```promql
sum by (tenant, user) (proxy_mysql_pool_in_use)
```

```promql
sum by (KeyspaceName) (rate(proxy_mysql_pool_wait_total[5m]))
```

## Prepared Statement Cache Metrics

### `proxy_mysql_prepared_stmt_cache_size`

Type: gauge

Labels: `tenant`, `user`, `KeyspaceName`, `ClusterId`

Description: Current number of cached MySQL prepared statements.

### `proxy_mysql_prepared_stmt_cache_hits_total`

Type: counter

Labels: `tenant`, `user`, `KeyspaceName`, `ClusterId`

Description: Total prepared statement cache hits.

### `proxy_mysql_prepared_stmt_cache_misses_total`

Type: counter

Labels: `tenant`, `user`, `KeyspaceName`, `ClusterId`

Description: Total prepared statement cache misses.

### `proxy_mysql_prepared_stmt_cache_evictions_total`

Type: counter

Labels: `tenant`, `user`, `KeyspaceName`, `ClusterId`

Description: Total prepared statement cache evictions.

### `proxy_mysql_prepared_stmt_cache_errors_total`

Type: counter

Labels: `tenant`, `user`, `KeyspaceName`, `ClusterId`

Description: Total prepared statement cache errors.

Example:

```promql
sum by (KeyspaceName) (rate(proxy_mysql_prepared_stmt_cache_hits_total[5m]))
/
(
  sum by (KeyspaceName) (rate(proxy_mysql_prepared_stmt_cache_hits_total[5m]))
  +
  sum by (KeyspaceName) (rate(proxy_mysql_prepared_stmt_cache_misses_total[5m]))
)
```

## Index Selection Metrics

### `proxy_index_selection_total`

Type: counter

Labels:

| Label | Values |
| --- | --- |
| `outcome` | Index selection outcome. |
| `rule` | Selection rule or `none`. |
| `index_type` | Selected index type or `unknown`. |
| `covering` | `true`, `false`. |
| `order_by` | `true`, `false`. |
| `back_table` | `true`, `false`. |
| `KeyspaceName` | Common label. |
| `ClusterId` | Common label. |

Description: Sampled index selection outcomes. The current sampling interval is once every 100 calls.

Example:

```promql
sum by (outcome, rule) (rate(proxy_index_selection_total[5m]))
```

## Notes

- Counter metrics should normally be queried with `rate()` or `increase()`.
- Gauge metrics represent the latest collected value.
- Histogram quantiles should be computed from `_bucket` series with `histogram_quantile()`.
- Labels with unresolved context use default values such as `KeyspaceName="unknown"` and `ClusterId="-1"`.
