11 Sep 2025
06:27 PM
- last edited on
24 Sep 2025
10:57 AM
by
Michal_Gebacki
I have timeseries metrics with common meta-data. The first is the count of "calls", the second is duration of calls. I'd like to create a heat map with the data to quickly identify distribution of call volume by response time across a full week. To do this would have x-axis as `day of the week`, y-axis as `range of durations`, and the value the number of calls.
I'm thinking something like:
Starting with this: `timeseries { avg=avg(otel.tyk.duration), calls=sum(otel.tyk.calls) }
...
Finishing with this: `| summarize calls=sum(calls), by:{range(duration), 100ms, day_of_week}`
Unsure of the middle and how to unwind the 2 timeseries metrics to get the day of week range, that would allow me to finish...
28 Nov 2025 12:04 PM
Hello, @ronmacdonald!
There's a documentation page about Heatmap visualization in the Dynatrace Documentation. Can you take a look at this please and let us know whether is it helping your issue in any way?
Thank you for collaboration!
28 Nov 2025 04:00 PM
Hi,
I tried to build the heatmap you described and here are the findings.
Using metrics alone (e.g., avg(duration) and sum(calls)) it’s not possible to derive a distribution of calls across duration buckets. Timeseries metrics don’t contain per-call durations, so DQL can’t “unwind” them into individual events.
To calculate the distribution correctly you need to use span-level data, which contains the actual duration of every call.
For example:
fetch spans
| fieldsAdd
day_of_week = getDayOfWeek(start_time),
duration_bucket = range(duration, duration(100, "ms"))
| summarize calls = count(), by: { day_of_week, duration_bucket }
| sort day_of_week ascThis produces a clean distribution table (day of week × duration bucket × calls).
However, Dynatrace heatmap does not support span-based queries, so even with correctly shaped data this cannot be visualized as a heatmap.
I also tried converting the buckets into strings:
fetch spans
| fieldsAdd
day = formatTimestamp(start_time, format:"EEE"),
bucket = concat(
toLong(duration / duration(100,"ms")) * 100,
"-",
toLong(duration / duration(100,"ms")) * 100 + 100,
" ms"
)
| summarize calls = count(), by: { day, bucket }
| sort day asc, bucket ascThis gives the right structure (string/string/number), but heatmap still rejects it because the heatmap visualization currently works only for metric-based queries, not for span/log/event queries.
You can try this on your data