Windows 11 Performance Counters Cheat Sheet
Sidebar
Operating Systems · Windows 11 Performance Counters Cheat Sheet
The counter path syntax, the counters worth watching for CPU, disk, network, processes and GPU, and the tools that read and log them (Performance Monitor, Resource Monitor, Get-Counter, typeperf). Every counter path below returned values on the PC this was written on (Windows 11 Pro, build 26300), as a normal user, and Get-Counter, Export-Counter and typeperf -o were run. The thresholds are common rules of thumb, not Microsoft limits, and are marked as such. Memory counters are on the Memory Troubleshooting sheet.
Counter Paths
\Object(instance)\CounterThe syntax: \Processor(_Total)\% Processor Time. (*) means every instance\\PCNAME\Object\CounterAdd a computer name to read another PC (needs remote access rights)_TotalThe all-instances sum for objects that have one (Processor, Process, PhysicalDisk)Get-Counter -ListSet *Every counter set (234 here); -ListSet Memory | % Counter lists one set's counters(Get-Counter -ListSet Process).PathsWithInstancesEvery concrete path, with instancesLocalised namesOn a non-English Windows the object and counter names are translatedReading Them
perfmonPerformance Monitor: add counters (green +), choose graph, histogram or report viewresmonResource Monitor: CPU, Memory, Disk, Network tabs with per-process detailperfmon /relReliability Monitor (a different tool: stability history)Task Manager > PerformanceThe summary graphs (see the Task Manager sheet)Get-CounterOne sample now; -Continuous until Ctrl+C; -SampleInterval 5 -MaxSamples 12 for one minutetypeperfCommand Prompt equivalent: typeperf "\Memory\Available MBytes" -sc 5CPU
\Processor(_Total)\% Processor TimeBusy share of all logical processors (the classic figure)\Processor Information(_Total)\% Processor UtilityBusy share scaled by current frequency; Task Manager's CPU graph matches this more closely (my understanding)\System\Processor Queue LengthThreads waiting for a processor. Sustained values above about 2 per logical processor mean CPU contention (rule of thumb)\System\Context Switches/secThread switches. Only meaningful compared with a baseline\Process(name)\% Processor TimeOne process; can exceed 100% on many cores (it sums the cores)\Processor(_Total)\% Interrupt TimeTime spent on hardware interrupts; persistently high points at a driver or device\Processor(_Total)\% DPC TimeDeferred procedure calls: also drivers. Same readingDisk
\PhysicalDisk(_Total)\% Disk TimeHow busy; can pass 100% on fast or parallel devices, so not a measure of saturation\PhysicalDisk(*)\Avg. Disk sec/ReadAverage read latency in seconds. Sustained above roughly 0.020 (20 ms) feels slow on a spinning disk (rule of thumb); SSDs should be far lower\PhysicalDisk(*)\Avg. Disk sec/WriteWrite latency, same reading\PhysicalDisk(*)\Current Disk Queue LengthRequests waiting right now; sustained growth means the disk cannot keep up\PhysicalDisk(*)\Disk Bytes/secThroughput, read + write\LogicalDisk(C:)\% Free SpaceSpace left on the volume(*) instances0 C: style names; map them to drives with Get-Disk, Get-VolumeOn this PC the disk counters are worth reading per disk: two USB drives log thousands of device errors (see the Event Viewer sheet), and their latencies are the first thing to check.
Network
\Network Interface(*)\Bytes Total/secThroughput per adapter (three instances active here)\Network Interface(*)\Output Queue LengthPackets waiting to send; sustained above 2 suggests a bottleneck (rule of thumb)\Network Interface(*)\Packets Received ErrorsReceive errors; non-zero and rising is a cable, driver or hardware lead\Network Interface(*)\Current BandwidthThe link speed in bits per secondInstance namesAdapter names have special characters replaced; list with (Get-Counter -ListSet 'Network Interface').PathsWithInstancesProcesses, Handles and System
\Process(_Total)\Handle CountSystem-wide open handles (192,314 here)\Process(_Total)\Thread CountSystem-wide threads\System\ProcessesNumber of processes\System\System Up TimeSeconds since boot (counts a fast restart's clock differently)\Process(name)\Working Set - PrivateOne program's private working set (firefox returned one instance here although it has many processes: the instance names are firefox, firefox#1, …)\Process(name)\Private BytesOne program's commit\Paging File(_Total)\% UsagePage file use (see Memory Troubleshooting)GPU
\GPU Engine(*)\Utilization PercentagePer-engine, per-process use (510 instances here). Sum by process or engine to match Task Manager\GPU Process Memory(*)\Dedicated UsageDedicated video memory per process (counter exists on current Windows; not checked here)\GPU Adapter Memory(*)\Dedicated UsagePer adapter (not checked here)Task Manager > Performance > GPUThe easier view for most checksLogging to a File
Get-Counter '\Memory\Available MBytes' -SampleInterval 5 -MaxSamples 720 | Export-Counter -Path C:\log\mem.csv -FileFormat csvOne hour at 5-second spacing to CSV (a small version was run here)typeperf "\Memory\Available MBytes" "\Processor(_Total)\% Processor Time" -si 5 -o C:\log\p.csv -ySeveral counters to CSV; -y overwrites without asking (run here with one counter)-f BIN / .blgExport-Counter -FileFormat blg writes a binary log Performance Monitor can openlogman create counterA background data collector set; creating one usually needs admin and the Performance Log Users rights (not tested here)relogConvert or trim a .blg logFor a leak, log every 30–60 seconds for many hours, and note what you were doing (the Memory Troubleshooting sheet explains why short samples mislead).
Get-Counter takes a pair of samples for you.