10 Nov 2025
09:54 PM
- last edited on
17 Nov 2025
10:35 AM
by
MaciejNeumann
For example, if I want a dashboard histogram chart for span durations, I can use the below dql to show bins of 100ms each:
fetch spans
| summarize count(), by:{range(duration, 100ms)}
Instead, can we create custom buckets, like 0-250ms, 250-500ms, 500ms-1s, 1s - 3s, etc.?
Solved! Go to Solution.
11 Nov 2025 12:26 PM
Yes — but not with range(). range(x, step) only makes equal-width bins. For custom buckets (0–250 ms, 250–500 ms, 500 ms–1 s, 1–3 s, …), build the buckets yourself via conditions and then group by that label.
Try this:
fetch spans
| fieldsAdd
bucket =
if(duration < 250ms, then: "0–250 ms", else:
if(duration < 500ms, then: "250–500 ms", else:
if(duration < 1s, then: "500 ms–1 s", else:
if(duration < 3s, then: "1–3 s", else: "≥3 s")
)
)
),
bucket_idx =
if(duration < 250ms, then: 1, else:
if(duration < 500ms, then: 2, else:
if(duration < 1s, then: 3, else:
if(duration < 3s, then: 4, else: 5)
)
)
)
| summarize spans = count(), by: { bucket, bucket_idx }
| sort bucket_idx asc
| fieldsRemove bucket_idx
you should recive this:
11 Nov 2025 02:56 PM
Awesome, thanks! I started exploring this same method, but instead of using a separate `bucket_idx` to handle the sorting, I only used millisecond-based buckets with a mix of substring and type conversion, like this:
fieldsAdd firstNum = toLong(substring(bucket,from:0,to:indexOf(bucket,"ms")))
| summarize by:{bucket, firstNum}, count()
| sort firstNum
| fieldsRemove firstNum
Your approach is great because I can use any unit in my bucket names.