2026
Grafana: Dashboards for Your Observability Stack
Metrics, logs and traces are only useful if you can look at them. Grafana sits in front of your data sources and turns raw numbers into dashboards you can actually read during an incident. Here is how the pieces fit together.
Metrics on their own are not very useful. A time series database full of numbers you cannot look at does not tell you much about what your system is doing. Grafana is the layer that turns those numbers into something you can actually read. It sits in front of your data sources, queries them and renders the results as dashboards you can share with anyone who needs to understand what is happening in production.
Most people encounter Grafana as the visualisation tool that sits on top of Prometheus. That pairing is common enough that the two are often mentioned together, but Grafana is not tied to Prometheus. It connects to dozens of different data sources and treats them all through the same dashboard interface. What makes it worth understanding on its own terms is that the dashboard model, the alerting system and the data source abstraction apply regardless of what is feeding it data.
Data sources
A data source in Grafana is a configured connection to a backend system that stores data. You define it once: the address, the credentials, any relevant options. After that, every panel in every dashboard can query it by selecting it from a dropdown. You never write connection strings into individual panels.
Prometheus
The most common pairing. Grafana queries Prometheus using PromQL and renders the results. Most Kubernetes monitoring setups centre on this combination.
Loki
Grafana's own log aggregation system. Uses a query language called LogQL that is deliberately similar to PromQL. Designed to work alongside Prometheus so metrics and logs share the same label set.
Tempo
Distributed tracing backend. Grafana can link from a log line or a metric spike directly into the trace that corresponds to that moment, which is where the observability stack starts to feel genuinely useful for debugging.
Elasticsearch / OpenSearch
Log and event data at larger scale. If your organisation already runs an ELK stack, Grafana can sit on top of it as a visualisation layer without replacing the storage backend.
PostgreSQL / MySQL
Direct SQL queries rendered as panels. Useful for business metrics and operational data that live in a relational database rather than a time series store.
The data source plugin system is what keeps Grafana general purpose. A dashboard that queries Prometheus today can be extended with a Loki panel tomorrow without rebuilding anything. The shared time range controls at the top of the dashboard apply across all panels regardless of which data source each one uses.
Dashboards and panels
A dashboard is a collection of panels arranged on a grid. Each panel contains a query, a visualisation type and display options. You build dashboards by combining panels that answer related questions so that someone looking at the screen can understand the state of a system without jumping between tools.
The time range selector at the top of a dashboard controls every panel simultaneously. When you zoom into the last fifteen minutes because something looks off, all panels update at once. This shared time context is what makes dashboards useful for incident investigation rather than just passive monitoring.
Time series
The panel you will use most often. It draws line graphs from time series data, which makes it the natural fit for anything Prometheus or Loki is feeding you. You can overlay multiple queries on the same graph, set thresholds that draw coloured lines across the chart and configure the legend to show min, max and current values inline.
Stat
A single large number with optional colour coding. Good for current CPU usage, active connections, total error count over the last hour. The colour thresholds make it easy to see at a glance whether something is in a healthy range without reading the number carefully.
Table
Renders query results in rows and columns. Useful when you need to compare values across multiple instances at a single point in time, like showing memory usage per node or error rates per service endpoint side by side.
Gauge
A radial dial that shows a value against a min and max range. Works well for things like disk usage percentage or connection pool saturation where the meaningful question is how close you are to a limit.
Logs
Displays log lines from a log data source like Loki. Supports filtering, log level colouring and linking directly from a log line into a related trace. Particularly useful placed next to a time series panel so you can correlate a spike in errors with the log output that explains it.
Variables
Variables are template parameters that make a dashboard reusable across multiple services, hosts or environments. Instead of building a separate dashboard for each Kubernetes namespace, you define a variable that queries the list of namespaces from Prometheus and renders a dropdown at the top of the page. Every panel query references the variable. Switching the dropdown reruns all queries for the selected value.
Using a variable in a PromQL panel query
sum(rate(http_requests_total{namespace="$namespace"}[5m])) by (handler)
$namespace resolves to whatever value is selected in the dropdown. The query runs fresh each time the selection changes.
label_values(kube_pod_info{namespace="$namespace"}, pod)
A variable query that populates a second dropdown with pod names scoped to the selected namespace.
Variables can also be chained. A namespace variable populates a pod variable which populates a container variable. Selecting a namespace filters the downstream options automatically. This is what lets a single well-built dashboard serve an entire platform rather than being rebuilt for each team that uses it.
Alerting
Grafana has a built-in alerting system that evaluates rules against your data sources on a schedule and routes notifications based on label matchers. It covers the same ground as Alertmanager in the Prometheus ecosystem but operates inside Grafana itself, which means alert rules live alongside the dashboards that display the same data.
Write an alert rule
A PromQL expression with a threshold condition. When the expression evaluates to true for a configured duration, the alert transitions to firing state.
Assign a contact point
Where the notification goes: Slack, PagerDuty, email, a webhook. Contact points are configured once and reused across many alert rules.
Configure a notification policy
Routing logic that maps alert labels to contact points. You can route database alerts to the database team and deployment alerts to the platform team using label matchers.
Set a silence if needed
During a planned maintenance window you can create a silence that matches specific labels. Matching alerts will not generate notifications for the duration of the silence.
One thing worth knowing about Grafana alerting is that it evaluates rules through a query engine inside Grafana, not directly inside the data source. For Prometheus this means the alert query runs as a PromQL expression against the Prometheus HTTP API rather than inside the Prometheus evaluation loop. In most setups this distinction does not matter. At high cardinality or under load it is worth being aware of.
Explore mode
Dashboards are for watching a system over time. Explore is for investigating a specific problem right now. It gives you a query editor connected directly to a data source without the overhead of building a panel. You run a PromQL query, look at the result, adjust it, look again. It behaves like an interactive scratchpad for your data.
Where Explore becomes genuinely useful is in the correlation workflow between Prometheus, Loki and Tempo. You see a spike in error rate in a metric query. You switch the data source to Loki and run a log query filtered to the same time window. A log line references a trace ID. You click it and Grafana opens the corresponding trace in Tempo. The investigation moves from numbers to logs to the specific request path that failed, all inside the same tool.
Dashboards as code
Grafana stores dashboards as JSON. You can export any dashboard, commit it to a repository and import it on a fresh instance. For teams running Grafana in Kubernetes, the Grafana Operator can watch a ConfigMap or a custom resource and automatically provision dashboards without anyone clicking through the UI.
Provisioning a dashboard from a ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: my-dashboard
labels:
grafana_dashboard: "1"
data:
dashboard.json: |
{ ... dashboard JSON ... }
Grafonnet is a library that lets you write dashboards in Jsonnet rather than raw JSON. It adds reusability through functions and variables in the traditional programming sense. If you find yourself maintaining twenty dashboards that share the same panel structure with minor differences per service, Grafonnet is worth the learning curve. For smaller setups, exporting JSON and keeping it in version control is enough.
Where it fits
Grafana is the part of the observability stack that people actually look at. Prometheus stores the numbers. Loki stores the logs. Tempo stores the traces. Grafana is what surfaces all of them in a form that is readable during an incident at two in the morning when you need to understand quickly what is broken.
The most common starting point is connecting it to an existing Prometheus instance and importing one of the community dashboards for node_exporter or Kubernetes. Those dashboards give you something immediately useful without building anything from scratch. From there, the natural next step is writing panels that answer questions specific to your own services: the metrics that matter for your workload rather than the generic infrastructure view.
A good dashboard is one that tells you what you need to know without requiring you to know what to look for. Building that takes iteration. You find out what is missing during the next incident, add it, adjust the layout, make it better. After a few rounds of that the dashboard starts to reflect how your system actually fails rather than how you imagined it might.