KQL · latency
The 20 slowest requests in the last hour
List the slowest individual requests from the last hour with operation name, duration, result code, cloud role and the operation_Id to trace each one.
requests latency
let lookback = 1h;
requests
| where timestamp > ago(lookback)
| top 20 by duration desc
| project
timestamp,
operation_Name,
duration,
resultCode,
success,
cloud_RoleName,
cloud_RoleInstance,
operation_Id,
itemCount Returns: Up to 20 individual requests from the last hour, slowest first, each with its operation name, duration in milliseconds, result code, cloud role and instance, and the operation_Id that opens its trace.
Pitfalls
- This lists stored rows. With sampling on, the slowest request of the hour may have been dropped, and a row with itemCount 5 stands for five requests that were not all this slow.
- One very slow route can fill all 20 rows. Use requests slower than a threshold by operation to see how widespread slowness is.
- duration is the server's time to handle the request, not what the user waited: network and browser time are not in it.
- Long-running requests such as file uploads or streaming responses top this list by design. Exclude them with a where clause on operation_Name.
How it works
Percentiles tell you that something is slow. This query hands you the actual slow requests, so you can open one and see where its time went. It is the natural next step after a latency alert or a jump on the duration timechart.
Line by line
let lookback = 1h;sets the window. An hour keeps the list close to “now”; widen it to24hto catch the worst requests of the day.top 20 by duration descsorts byduration(milliseconds) and keeps the first 20 rows. It is one step that does the work oforder byplustake.projectpicks the columns worth reading.operation_Nameis the route-level name (such asGET /orders/{id}), so you can tell at a glance whether the slow ones share a route.resultCodeandsuccessshow whether they also failed; a slow request that failed is often a timeout.cloud_RoleNameandcloud_RoleInstanceshow which service and which machine or container served it. Five slow rows on one instance and none elsewhere points at that instance, not at the code.operation_Idis the ID every item in the same distributed operation shares. Paste it into the end-to-end trace query to see the dependencies, logs and exceptions behind that one request.itemCountsays how many requests the row stands for under sampling. Show it, so nobody reads 20 rows as “only 20 slow requests”.
When to use it
Use it during an incident, when you want specific examples rather than statistics, and when a p99 looks wrong and you want to see whether it comes from one freak request or many. If most rows share one route, move on to requests slower than a threshold for that route to see what share of its traffic is affected.
If the slowest requests all come from one service, the correlation guide explains how operation_Id ties them to the calls they made.
Variations
- Exclude a long-running route: add
| where operation_Name !in ("POST /upload", "GET /export")beforetop. - Only failures: add
| where tostring(success) =~ "false"beforetop. - Workspace tables: use
AppRequests,TimeGenerated,OperationName,DurationMs,ResultCode,AppRoleName,AppRoleInstance,OperationIdandItemCount.