Grafana lets you overlay data from wildly different sources onto a single graph, and the secret sauce isn’t some arcane query language, but a simple transformation step you can apply after the data arrives.

Let’s say you’ve got Prometheus metrics for your application’s request latency and an InfluxDB database holding user session durations. You want to see if high latency correlates with shorter sessions.

Here’s how you’d set it up:

First, you’d add both your Prometheus and InfluxDB datasources to Grafana. Then, you’d create a new panel and add a query for Prometheus, something like avg(http_request_duration_seconds_bucket{le="0.1"}) by (job). You’d set the alias to "High Latency Requests".

Next, you’d add a second query, this time for InfluxDB. You might query SELECT mean("duration") FROM "sessions" WHERE $timeFilter GROUP BY time($__interval). You’d alias this as "Average Session Duration".

At this point, if you look at the panel, you’ll see two graphs, but they’re probably not on the same scale and might not even be aligned correctly. This is where the magic happens.

Below your queries, you’ll see a tab labeled "Transform". Click it.

The default transformation is usually "Add field from calculation". We’re going to use a few of these.

First, let’s make sure both datasets are treated as time-series data. Select "Convert field type". For the Prometheus query, set "Field to convert" to "High Latency Requests", "Field with type" to "time", and "Target type" to "Time". Do the same for the InfluxDB query, making sure the "time" field is identified. This ensures Grafana understands both are temporal.

Now, the crucial step: combining them. We want to align our InfluxDB session data to the Prometheus time buckets. Select "Group by". For "Group by", choose "time". For "Calculations", select "last not null". This will take the last known session duration for each time interval.

Next, we need to ensure the scales are comparable, or at least that we can visually interpret them. Select "Add field from calculation". For "Mode", choose "Binary operation". For "Operation", pick "Multiply". For the first "Field", select "Average Session Duration". For the second "Field", enter a scaling factor, say 0.001. This converts our session durations from milliseconds to seconds, making them directly comparable to latency. You’ll need to experiment with this scaling factor based on your data’s typical ranges.

Your panel now shows two series, both derived from different datasources, but presented on the same time axis and with a meaningful scale relationship. You can now visually inspect if periods of high latency correspond to shorter session durations.

The surprising thing about this process is that Grafana doesn’t require a unified query language across datasources. It pulls raw data, then uses these transformation steps to massage it into a usable format for visualization, effectively creating a temporary, unified view.

The real power comes when you start using more advanced transformations. For instance, you can use "Filter data by values" to only show periods where latency exceeds a certain threshold, and then see the average session duration during those specific high-latency periods. Or you can use "Outer join" to combine fields from different series based on their timestamp, allowing you to, for example, overlay a calculated error rate from logs (another datasource) onto your performance metrics.

A common pitfall is not understanding how __interval works in the context of transformations. When you group by "time", Grafana uses the dashboard’s __interval variable, which dynamically adjusts based on zoom level and data density. If your transformations don’t account for this, your aligned data might appear to shift relative to the original series. Always ensure your "Group by" calculations are compatible with the dashboard’s time resolution.

Once you’ve mastered combining and transforming data, the next logical step is exploring Grafana’s alerting capabilities based on these combined series.

Want structured learning?

Take the full Grafana course →