---
id: platform/metrics
title: Metrics
description: Inspect service and datastore time series, query metrics through the API, and distinguish absent telemetry from zero usage.
keywords: [bex, metrics, cpu, memory, latency, bandwidth, observability]
last_updated: 2026-09-23
---

Use metrics to identify changes in resource consumption and application
traffic. Bex's dashboard and API expose time series from configured telemetry
backends. Metric availability varies by workload and backend; missing data is
not the same as zero usage or a healthy service.

![Bex service CPU and memory charts](/img/dashboard/service-metrics.webp)

## Choose a signal

| Signal | What to investigate |
| --- | --- |
| CPU and memory | Resource pressure, sustained growth, and capacity headroom. |
| Instance count | Scaling or availability changes alongside resource usage. |
| HTTP requests and latency | Traffic changes and slow responses for serving workloads. |
| Bandwidth | Changes in response traffic and transfer volume. |
| Datastore disk/capacity and connections | Storage pressure and excessive client connections. |
| Replication lag | Whether a supported database replica is falling behind. |
| Key Value memory and connections | Cache/queue pressure and client load. |

A worker has no public request stream, and a static site has no per-site
application process. Do not assume every metric family applies to every resource.

## Query a service metric

Set `BEX_API_URL`, an authorized `BEX_TOKEN`, and `SERVICE_ID`:

```bash
curl --fail-with-body --get "$BEX_API_URL/v1/metrics/cpu" \
  -H "Authorization: Bearer $BEX_TOKEN" \
  --data-urlencode "resource=$SERVICE_ID"
```

Other service endpoints include `/v1/metrics/memory`, `/instance-count`,
`/http-requests`, `/http-latency`, and `/bandwidth` under the same metrics prefix.
Use `startTime` and `endTime` as RFC 3339 timestamps and `resolutionSeconds`
for the sampling resolution when you need a specific incident window.
The response contains time series; inspect labels and timestamps before
aggregating across instances or comparing periods.

Latency queries accept `quantile`, for example `quantile=0.95`. A percentile
is not an average: use it to observe the slower tail of requests. Keep the
same time window and resolution when comparing a deployment with its predecessor.

Datastore metrics have separate endpoints and resource-kind validation. Use
the database's or Key Value store's metrics panel to choose the applicable
signal rather than passing a datastore id to an application-only endpoint.

These endpoints return telemetry time series, not billing meters. For the
metered totals behind an invoice — with coverage states and an advisory
estimate — see [Month-to-date usage](./usage.md).

## Interpret charts with context

Correlate resource changes with deployments, request volume, instance count,
and [logs](./logging.md). A memory increase after each request can indicate a
leak; a flat high-memory cache can be intentional. Higher CPU during a build
is different from sustained runtime saturation. A lower request rate may mean
less demand or a failure before requests reach the application.

Before [scaling](./scaling.md), check whether the bottleneck is the application,
its database, an external dependency, or cluster capacity. More replicas also
increase connections and other shared load.

## If a chart is empty or unavailable

Check resource type, time bounds, resolution, and whether the resource ran
during that interval. Verify backend collection and retention on a self-hosted
instance. Bex reports unavailable telemetry when required sources are missing;
do not replace that state with zeros in monitoring code.

Instance query-window and fan-out limits can reject overly broad requests.
Narrow the window or resource set and use a suitable resolution. See
[Health checks](./health-checks.md) for readiness/restart behavior and
[Notifications](./notifications.md) for deployment and lifecycle alerts.
