Grafana variables are the secret sauce for building dashboards that don’t just display data, but adapt to it, letting you slice and dice the same visualizations across different dimensions without copy-pasting.
Let’s say you have a fleet of servers, and you want to see the CPU usage for each of them on the same dashboard. Instead of creating a separate panel for server_a, server_b, and server_c, you use a variable.
Here’s a dashboard showing disk I/O for a single host. Notice the dropdown at the top:
[Image: Grafana dashboard with a single panel showing disk I/O, and a dropdown menu at the top labeled "Host" with options like "server-01", "server-02", "server-03".]
When you select "server-02" from the "Host" dropdown, all panels on the dashboard that use the $Host variable automatically update to show data for server-02.
[Image: The same Grafana dashboard, but now the "Host" dropdown is set to "server-02", and the disk I/O panel shows data for "server-02".]
This isn’t magic; it’s templating. Grafana queries are dynamically built using the selected variable values.
To set this up, you’d go to your dashboard’s "Settings" (the gear icon), then "Variables." You’d add a new variable.
Variable Configuration:
- Name:
Host(this is what you’ll use in your queries, prefixed with$) - Type:
Query - Data source: Your Prometheus, InfluxDB, or other data source.
- Query: This is the crucial part. For Prometheus, it might look like
label_values(node_uname_info, instance). This tells Grafana to ask Prometheus for all unique values of theinstancelabel. - Refresh:
On Dashboard LoadorOn Time Range Changeare common. - Sort:
Alphabetical (asc)is usually fine. - Selection Options: Enable "Multi-value" and "Include All option" if you want to select multiple hosts or an "All" option.
Now, in your panel’s query editor, instead of hardcoding a hostname, you’d use the variable. For Prometheus, your query might change from:
rate(node_disk_read_bytes_total{instance="server-01"}[5m])
to:
rate(node_disk_read_bytes_total{instance=~"$Host"}[5m])
The =~ operator is key here. It means "matches regex." If you enable multi-value selection, $Host will expand to something like (server-01|server-02|server-03), allowing the query to fetch data for all selected hosts. If "All" is selected and multi-value is enabled, it will effectively query all available hosts.
You can repeat this for any dimension: environments (dev, staging, prod), services (auth, user, payment), regions (us-east-1, eu-west-2), or even specific metrics if your data source supports it.
The real power comes when you nest variables. Imagine a dashboard where you first select an Environment (dev, prod), and then a Host variable dynamically populates only with hosts from the selected environment. The Host variable’s query would then depend on the Environment variable: label_values(node_uname_info{env="$Environment"}, instance).
When you use a variable that accepts multiple values, like $Host with multi-value enabled, Grafana expands it into a regex-compatible string for the query. For example, if you select server-01 and server-03, the query might become instance=~"server-01|server-03". The ~ operator in Prometheus (and similar operators in other data sources) signifies a regular expression match. This is why you use "$Host" (with quotes) in your query string to ensure the expanded regex is treated as a single string literal by the data source.
The "All" option for a multi-value variable is particularly clever. When "All" is selected, Grafana typically expands the variable to match all possible values returned by the variable’s query. If your query for Host returns server-01, server-02, server-03, selecting "All" will generate a regex like (server-01|server-02|server-03) for the $Host variable, effectively querying everything. This avoids needing to manually update the dashboard when new hosts are added.
The most surprising aspect of Grafana variables is their ability to dynamically alter not just the data displayed, but also the structure of your dashboard. You can use variables to control which rows or panels are displayed at all, using the Hide Row or Hide Panel options within the panel/row’s "General" settings, based on variable selections. For instance, you could have a "Production Specific Metrics" row that only appears when the Environment variable is set to prod. This makes dashboards incredibly compact and relevant, showing only what the user needs at that moment.
The next step is to explore template variable cascading and advanced query options for more complex filtering scenarios.