KQL · operations
CPU and available memory per instance as a timechart
Chart process CPU and available memory for each instance in 5-minute bins from the performanceCounters table, with notes on which counters you have.
performanceCounters operations
let lookback = 24h;
performanceCounters
| where timestamp > ago(lookback)
| where counter in ("% Processor Time Normalized", "Available Bytes")
| summarize
cpu_pct = avgif(value, counter == "% Processor Time Normalized"),
available_gb = avgif(value, counter == "Available Bytes") / 1e9
by bin(timestamp, 5m), cloud_RoleInstance
| order by timestamp asc
| render timechart Returns: Two lines per instance over the last 24 hours in 5-minute steps, the process CPU divided by the processor count and the machine's available memory in gigabytes.
Pitfalls
- Which counters exist depends on the SDK and platform. Run performanceCounters | summarize count() by category, counter, instance first and adjust the names.
- The plain % Processor Time counter for the process isn't divided by the processor count; the Normalized one is. If you only have the plain counter, divide by the core count yourself.
- Available Bytes is machine memory, shared by every process on the host. For your process alone, chart Private Bytes.
- Performance counters are never sampled and have no itemCount column, so plain averages are right here.
How it works
When one instance is slower than its siblings, the first suspects are CPU and memory. The performanceCounters table holds them: one row per counter per instance at a regular interval, with the category, counter and instance names split into their own columns and the reading in value.
Line by line
where counter in (...)keeps two counters:% Processor Time Normalized(the process’s CPU use divided by the logical processor count, as Microsoft defines it) andAvailable Bytes(free physical memory on the machine). Both are in Microsoft’s default counter lists for ASP.NET and ASP.NET Core, and in the set the Distros export to this table.avgif(value, counter == "...")averages each counter’s readings separately in the samesummarize, so both end up as columns on one row.available_gbdivides bytes by1e9so memory and CPU sit on comparable scales on one chart.by bin(timestamp, 5m), cloud_RoleInstancegives one point per instance per 5 minutes.cloud_RoleInstanceis the machine or container, not the counter’s owninstancecolumn, which Microsoft notes usually holds a process or application name.render timechartdraws a CPU line and a memory line for each instance.
Which counters do you have?
Microsoft’s own starting point for this table is a list of what is there:
let lookback = 24h;
performanceCounters
| where timestamp > ago(lookback)
| summarize readings = count(), avg_value = avg(value) by category, counter, instance
Classic Windows performance counters appear only where the SDK can read them; cross-platform .NET apps report event counters instead, and some platforms report fewer. The performance counters guide explains which collector produces what, including for console and worker apps.
Reading the chart
CPU pinned near 100 on one instance while the others idle points at that instance’s workload: a stuck thread, a hot partition, a noisy neighbour. Available memory falling steadily until a restart is the shape of a leak. Compare the instance with request latency by cloud role and find which version it runs with cloud role instances and versions.
Variations
- One measure per chart: drop one of the two
avgif()lines; with many instances, two lines each gets crowded. - Workspace tables: use
AppPerformanceCounters,TimeGenerated,Counter,Category,Instance,ValueandAppRoleInstance.
Sources, checked
- Application Insights Classic API 2.x (performance counters in Log Analytics)
- Application Insights telemetry data model (system and process counters)
- Metrics in Application Insights (counters exported by the Distros)
- avgif() (Kusto)
- Telemetry sampling in Application Insights (types never sampled)
- Migrate an Application Insights classic resource to a workspace-based resource (table schemas)