APM Tips

KQL · dependencies

Dependency failure rate by type and target

The share of failed outgoing calls per dependency type and target over the last 24 hours, sampling-adjusted, with an example failing result code.

Updated

dependencies dependencies

let lookback = 24h;
dependencies
| where timestamp > ago(lookback)
| summarize
    calls = sum(itemCount),
    failed = sumif(itemCount, tostring(success) =~ "false"),
    example_result_code = take_anyif(resultCode, tostring(success) =~ "false")
    by type, target
| where failed > 0
| extend failed_pct = round(100.0 * failed / calls, 2)
| order by failed desc

Returns: One row per dependency type and target with at least one failed call, showing total calls, failed calls, the failed percentage and one result code from a failed call.

Pitfalls

  • What counts as a failed dependency is decided by the instrumentation: an HTTP call that got a 404 may be recorded as failed even when your code expects it and handles it.
  • Retries inflate both columns. Three attempts that end in success leave two failed calls behind, and the request may still succeed.
  • target is what the instrumentation recorded. Calls through a proxy, gateway or service mesh all land on that name, hiding which back end failed.
  • Counts use sum(itemCount); a raw row count understates calls when sampling is on.

How it works

When requests start failing, the cause is often downstream: a database that refuses connections, an API that times out, a storage account that throttles. This query ranks everything your app calls by how often those calls fail, so a struggling dependency stands out in one table.

Line by line

  • let lookback = 24h; sets the window.
  • calls = sum(itemCount) counts outgoing calls the sampling-aware way; each stored row stands for itemCount calls.
  • failed = sumif(itemCount, tostring(success) =~ "false") counts the failed ones. The classic schema stores success as text, and the comparison works on either form.
  • take_anyif(resultCode, ...) picks one result code from a failed call. The data model gives SQL error codes and HTTP status codes as examples of what resultCode holds for a dependency, which usually tells you the kind of failure at a glance: 429 throttling, 503 unavailable, a SQL timeout number.
  • by type, target groups by the kind of call (the data model’s low-cardinality type name, such as SQL or HTTP) and its destination (a server name or host address).
  • failed_pct is the failed share of calls to that target.
  • order by failed desc ranks by volume of failures. Sort by failed_pct to find the targets that fail most often relative to how much you call them.

Reading the result

A target with a high failed_pct and high volume is hurting many requests right now. A low percentage on a very busy target can still be thousands of failed calls a day, often absorbed by retries until the day they aren’t. When a target fails, check its latency with slowest dependencies by target: failures that arrive at the timeout value are timeouts, not refusals.

Whether a failed call is visible at all depends on the instrumentation. The agent-based dependency tracking guide covers which calls each collection method records and what it can miss.

Variations

  • Trend for one target: add | where target == "orders-db.example.net", group by bin(timestamp, 15m), sort by timestamp and add | render timechart.
  • Which operations suffer: group failed calls by operation_Name instead of type, target.
  • Workspace tables: use AppDependencies, TimeGenerated, DependencyType (the classic type), Target, Success, ResultCode and ItemCount.

Sources, checked

  1. Application Insights telemetry data model (dependency type, target, success, resultCode)learn.microsoft.com · checked
  2. sumif() (Kusto)learn.microsoft.com · checked
  3. take_anyif() (Kusto)learn.microsoft.com · checked
  4. Migrate an Application Insights classic resource to a workspace-based resource (table schemas)learn.microsoft.com · checked
  5. Telemetry sampling in Application Insightslearn.microsoft.com · checked