Latency, traffic, errors, saturation. Four panels, one query shape each, and a service has a dashboard that answers the first question in almost any incident.

The golden signals framework is old enough to feel like a cliche, and it earns that reputation by still being the fastest way to answer the first question of any incident: what actually changed. Building the four panels by hand, rather than starting from a template, is worth doing once to understand exactly what each query is doing.

1. Latency

Percentiles, not averages, an average latency chart can look perfectly flat while ten percent of users wait five seconds.

from traces
| where service.name == "checkout-api"
| summarize p50(duration), p95(duration), p99(duration) by bin(timestamp, 1m)

2. Traffic

Simple request volume, but grouped by route, a flat total line can hide one route silently dropping to zero while another compensates.

from traces
| where service.name == "checkout-api"
| summarize count() by bin(timestamp, 1m), route

3. Errors

Rate, not raw count, a raw error count chart makes low-traffic overnight hours look deceptively calm and high-traffic peak hours look deceptively alarming, even at the same underlying failure rate.

from traces
| where service.name == "checkout-api"
| summarize countif(status_code >= 500) * 1.0 / count() by bin(timestamp, 1m)

4. Saturation

The one signal that does not come from traces. Pull it from infrastructure metrics instead, and pick the resource actually likely to run out first for this specific service, CPU for a compute-bound one, connection pool usage for a database-bound one.

from metrics
| where metric.name == "process.cpu.utilization"
| where service.name == "checkout-api"
| summarize avg(value) by bin(timestamp, 1m)

Stack the four panels in that order, latency at the top, saturation at the bottom, and the dashboard reads left to right as a story: what users felt, how much traffic there was, how much of it failed, and what resource was closest to its limit. That ordering is not arbitrary, it mirrors the order most people actually reason through an incident.

  • Chart latency as percentiles, never as an average.
  • Break traffic down by route, a flat total can hide a single dead endpoint.
  • Chart error rate, not raw error count, so the baseline holds across traffic levels.
  • Pick the saturation metric that actually matters for this service, not a generic default.