Heatmap, state timeline and logs panels

Grafana · Practical · 10 min

Averages hide the shape of latency and up/down states; these visualizations show distribution and state changes that a line graph can't.

Heatmap shows how a distribution changes over time: the X axis is time, the Y axis the value buckets, and colour the count in each cell. For a Prometheus histogram, query the _bucket series summed by le and set the query Format to Heatmap: Grafana then sorts the buckets, converts cumulative counts into per-bucket counts and labels the Y axis with the bucket bounds. Native histograms are supported directly. Options cover the colour scheme and scale (exponential works well for latency), Y axis unit, bucket count for raw data, and Calculate from data, which bins plain time series yourself when the source has no buckets. Exemplars appear as dots on the heatmap.

State timeline shows discrete values per series as coloured bars along time: service up or down, deployment phase, feature flag state, alert state. Feed it values and give them meaning with value mappings (1 to "up" in green, 0 to "down" in red) or thresholds; Merge equal consecutive values collapses runs into one bar. Status history is the same idea on a periodic grid, one cell per interval, nicer for many series over long ranges.

The Logs visualization embeds a Loki (or Elasticsearch) query on a dashboard, with options to show time, wrap lines, prettify JSON, deduplicate and order. Keep the query narrow and pair it with the dashboard variables so logs follow the selected service.

Together with time series these cover most needs; the Grafana catalogue also has Candlestick, Node graph, Geomap, Canvas and Flame graph for specialised data.

Example

# Heatmap panel: request latency distribution
# Query options -> Format: Heatmap, Type: range
sum by (le) (rate(http_request_duration_seconds_bucket{job="api"}[$__rate_interval]))
# Y axis unit: seconds; colour scale: exponential

# State timeline: target health, value mappings 1 -> UP (green), 0 -> DOWN (red)
# Legend: {{instance}}
max by (instance) (up{job="api"})

# Status history: did the nightly job succeed each day? (0 = failed, 1 = ok)
max_over_time(job_last_run_success{job="etl"}[1d])

# Logs panel (Loki) following the dashboard variable
{app="$service", env="$env"} | json | level="error"

Remember

  • Histogram buckets summed by le + Format: Heatmap = latency distribution over time
  • State timeline needs value mappings to turn numbers into named, coloured states
  • Logs panel embeds a narrow Loki query that follows the dashboard variables

Watch out for

  • Forgetting to sum by le, so every instance contributes its own set of buckets and the heatmap is noise.

Check yourself

  1. What must a Prometheus query for a heatmap panel do?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: grafana.com/docs/grafana/latest/panels-visualizations/visualizations/heatmap/