APM Tips

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.

Updated

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 to 24h to catch the worst requests of the day.
  • top 20 by duration desc sorts by duration (milliseconds) and keeps the first 20 rows. It is one step that does the work of order by plus take.
  • project picks the columns worth reading. operation_Name is the route-level name (such as GET /orders/{id}), so you can tell at a glance whether the slow ones share a route. resultCode and success show whether they also failed; a slow request that failed is often a timeout.
  • cloud_RoleName and cloud_RoleInstance show 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_Id is 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.
  • itemCount says 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") before top.
  • Only failures: add | where tostring(success) =~ "false" before top.
  • Workspace tables: use AppRequests, TimeGenerated, OperationName, DurationMs, ResultCode, AppRoleName, AppRoleInstance, OperationId and ItemCount.

Sources, checked

  1. top operator (Kusto)learn.microsoft.com · checked
  2. Application Insights telemetry data modellearn.microsoft.com · checked
  3. Telemetry sampling in Application Insightslearn.microsoft.com · checked
  4. Migrate an Application Insights classic resource to a workspace-based resource (table schemas)learn.microsoft.com · checked