The alert says "failed requests above threshold" or users say "the app is slow". Application Insights already has the data. You need the query that answers "what broke, since when, and is it us or a dependency?" in under five minutes. These are the queries to keep open.
Which table names to use
The same telemetry has two sets of names, depending on where you run the query.
| Where you run the query | Requests | Dependencies | Exceptions | Traces | Availability tests |
|---|---|---|---|---|---|
| Log Analytics workspace (workspace-based) | AppRequests | AppDependencies | AppExceptions | AppTraces | AppAvailabilityResults |
| Application Insights resource > Logs (classic schema) | requests | dependencies | exceptions | traces | availabilityResults |
Column names change too: TimeGenerated vs timestamp, DurationMs vs duration, AppRoleName vs cloud_RoleName, OperationId vs operation_Id. The queries below use the workspace names, with the classic equivalents noted where they differ.
Tip
If sampling is on, each row can stand for several requests. Count with
sum(ItemCount)(sum(itemCount)in classic) instead ofcount(), or your error rates and volumes will be too low.
Run the queries from the CLI
az extension add --name application-insights
az monitor app-insights query -g rg-web-prod --app appi-web-prod \
--analytics-query "requests | where timestamp > ago(1h) | summarize sum(itemCount) by success" -o table
Against the workspace (pass the workspace GUID, not the resource ID):
az monitor log-analytics query -w 00000000-0000-0000-0000-000000000000 \
--analytics-query "AppRequests | where TimeGenerated > ago(1h) | summarize sum(ItemCount) by Success" -o table
Is it failing, and since when?
Failure rate in 5-minute bins. Check whether it started suddenly, which usually means a deployment or config change, or crept up, which usually means load or a dependency:
AppRequests
| where TimeGenerated > ago(6h)
| summarize total = sum(ItemCount), failed = sumif(ItemCount, Success == false) by bin(TimeGenerated, 5m)
| extend failRatePct = round(100.0 * failed / total, 2)
| render timechart
Which operations fail, and with which result codes:
AppRequests
| where TimeGenerated > ago(1h) and Success == false
| summarize failures = sum(ItemCount) by Name, ResultCode, AppRoleName
| top 20 by failures
Reading the result codes
| Result code pattern | Usually means | Look next at |
|---|---|---|
Mostly 500 on one operation | Code exception | AppExceptions for that operation |
500 across all operations | Shared dependency down, or bad config or secret | AppDependencies failures |
502 / 503 with no request rows | Requests never reached the app (platform, gateway, restart) | App Service diagnostics, Front Door or Application Gateway logs |
401 / 403 spike | Expired token or secret, or a role assignment change | Entra sign-in logs, Activity Log |
429 | Your own throttling, or a dependency passing its 429s through | AppDependencies where ResultCode == "429" |
404 spike after a release | Route change or missing static content | Request Url values |
Is it slow, and where?
Use percentiles, not averages. One stuck call can drag an average around, but p95 shows what users actually feel:
AppRequests
| where TimeGenerated > ago(6h)
| summarize p50 = percentile(DurationMs, 50), p95 = percentile(DurationMs, 95), p99 = percentile(DurationMs, 99)
by bin(TimeGenerated, 5m)
| render timechart
The slowest operations right now:
AppRequests
| where TimeGenerated > ago(1h)
| summarize calls = sum(ItemCount), p95 = percentile(DurationMs, 95) by Name
| where calls > 20
| top 15 by p95
Which dependency is to blame
AppDependencies
| where TimeGenerated > ago(1h)
| summarize calls = sum(ItemCount),
failed = sumif(ItemCount, Success == false),
p95 = percentile(DurationMs, 95)
by Target, DependencyType, AppRoleName
| order by p95 desc
Target is the host (SQL server, storage account, API). DependencyType is SQL, HTTP, Azure blob and so on. Exact type strings depend on the SDK and version, so check your own data first. In classic, use dependencies with target, type and duration.
The single dependency call that made one slow request slow:
let slowOps = AppRequests
| where TimeGenerated > ago(1h) and DurationMs > 5000
| project OperationId;
AppDependencies
| where TimeGenerated > ago(1h) and OperationId in (slowOps)
| summarize calls = sum(ItemCount), p95 = percentile(DurationMs, 95), maxMs = max(DurationMs) by Target, Name
| top 10 by maxMs
Which exception is new?
Exceptions grouped by problem, with the first time each one appeared. A firstSeen that lines up with the start of the incident is the one to chase:
AppExceptions
| where TimeGenerated > ago(24h)
| summarize occurrences = sum(ItemCount), firstSeen = min(TimeGenerated), lastSeen = max(TimeGenerated),
sample = take_any(OuterMessage)
by ProblemId, ExceptionType, AppRoleName
| order by firstSeen desc
Compare exceptions with the same window before a deployment:
let deployTime = datetime(2026-11-02 08:30);
AppExceptions
| where TimeGenerated between ((deployTime - 2h) .. (deployTime + 2h))
| extend period = iff(TimeGenerated < deployTime, "before", "after")
| summarize n = sum(ItemCount) by ProblemId, period
| evaluate pivot(period, sum(n))
| order by after desc
Follow one failed request end to end
Take an OperationId from any query above and pull every piece of telemetry for it:
let op = "4bf92f3577b34da6a3ce929d0e0e4736";
union AppRequests, AppDependencies, AppExceptions, AppTraces
| where OperationId == op
| project TimeGenerated, Type, AppRoleName, Name, Target, DurationMs, Success, ResultCode, OuterMessage, Message
| order by TimeGenerated asc
In classic, use union requests, dependencies, exceptions, traces and filter on operation_Id.
Which instance or version is bad?
When only some servers or a new version fail:
AppRequests
| where TimeGenerated > ago(1h)
| summarize total = sum(ItemCount), failed = sumif(ItemCount, Success == false) by AppRoleInstance, AppVersion
| extend failRatePct = round(100.0 * failed / total, 2)
| order by failRatePct desc
If one AppRoleInstance stands out, restart or remove that instance. If one AppVersion stands out, roll back the release. AppVersion is only filled in if the app or SDK sets it.
Availability tests failing
AppAvailabilityResults
| where TimeGenerated > ago(6h)
| summarize runs = count(), failed = countif(Success == false) by Name, Location
| where failed > 0
| order by failed desc
Failures from every location mean the app or its DNS or certificate is broken. Failures from one location usually mean a network path or regional problem.
Warning
No data is not the same as no errors. If request volume drops to zero, the app may be down, ingestion may be delayed, or a daily cap may have been reached. Check
AppRequests | summarize max(TimeGenerated)before you assume it's quiet.
Prevent it next time
- Turn the failure-rate and dependency p95 queries into log search alert rules, using bins and thresholds that match normal traffic.
- Set
AppRoleName(cloud role name) on every service, so a shared workspace can tell them apart. - Record deployments as annotations or in a known table, so the before/after query takes one lookup.
- Save these queries as a workbook or query pack for the team, rather than in someone's browser history.