Azure Workbook Tile Returns “Query Returned No Results” for VMs Despite Perf & InsightsMetrics Data Being PresentAzure Workbook
issue with an Azure Monitor shared dashboard (Resource-Monitor-v4) that contains workbook tiles displaying Top 10 CPU-consuming processes per VM using a KQL join between Perf
and InsightsMetrics
. This setup was previously working fine for all VMs, but recently only one VM (WebServer3
) consistently returns data, while all others (AppServer2, AppSer, etc.)
show:The query returned no results.
This behavior is breaking our visibility into VM-level performance. We’ve validated everything from query structure, agent connectivity, data flow, and DCR, yet the issue persists.
Details of the Setup
- Workspace: Single Log Analytics workspace
- Telemetry source: Azure VMs connected via DCR (Data Collection Rules)
- Connected VMs:
- AppServer2
- AppServ...etc
- WebServ (Only VM returning data)
- And several others
- Workbook Configuration:
- Auto-refresh: 5 minutes
- Query time window: Last 30 minutes
- Query aggregates
% Processor Time
fromPerf
table - Joins with CPU count from
InsightsMetrics
to normalize by core count. Original Working KQL Query (Still Works Only for One VM):
Observations and Diagnostics Heartbeat Logs:Perf | where ObjectName == "Process" and CounterName == "% Processor Time" and InstanceName != "_Total" and InstanceName != "Idle" | join kind=inner ( InsightsMetrics | where Namespace == "Processor" | where Name == "UtilizationPercentage" | where Computer contains "AppServer2" | extend tagValues = parse_json(Tags) | extend totalCpus = toint(tagValues["vm.azm.ms/totalCpus"]) | project TimeGenerated, Computer, TotalCPUs = totalCpus ) on Computer | summarize MaxCPU = max(CounterValue) by Computer, TotalCPUs, bin(TimeGenerated, 1m), InstanceName | extend NormalizedCPU = MaxCPU / (TotalCPUs * 100) | summarize MaxNormalizedCPU = max(NormalizedCPU) by Computer, InstanceName | order by MaxNormalizedCPU desc | take 10
- All affected VMs are connected and sending Heartbeat logs to the workspace.
- Verified in Log Analytics:
Heartbeat | summarize by Computer
– lists all expected machines.
Performance Data is Available:
Perf
| where TimeGenerated > ago(1h)
| where ObjectName == "Process" and CounterName == "% Processor Time"
| summarize Count = count() by Computer
CPU Info is Available in InsightsMetrics
:
InsightsMetrics
| where TimeGenerated > ago(1h)
| where Namespace == "Processor" and Name == "UtilizationPercentage"
| extend tagValues = parse_json(Tags)
| extend TotalCPUs = toint(tagValues["vm.azm.ms/totalCpus"])
| where isnotnull(TotalCPUs)
| summarize by Computer, TotalCPUs
Workbook Visual Impact
- Tiles for
AppServer2
,AppSer
,AppSeN
, etc., all show: “The query returned no results.”
- as the behavior of KQL
join
changed in Log Analytics? - Could this be a regression or backend ingestion delay?
- Is this related to subtle mismatches in how
TimeGenerated
alignment works betweenPerf
andInsightsMetrics
? - Are there any known issues or changes in Log Analytics join behavior, sampling delays, or InsightsMetrics ingestion?
- Is there a more reliable way to join Perf with InsightsMetrics for normalized CPU data
Any insights would be greatly appreciated. We've done extensive testing and are trying to restore full visibility into our VM CPU behavior via the dashboard.