{"id":625,"date":"2026-08-14T23:08:03","date_gmt":"2026-08-14T23:08:03","guid":{"rendered":"https:\/\/windows-vps.org\/blog\/?p=625"},"modified":"2026-08-14T23:08:03","modified_gmt":"2026-08-14T23:08:03","slug":"windows-server-performance-monitoring-perfmon-counters","status":"publish","type":"post","link":"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/","title":{"rendered":"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Windows Server ships with a full performance-monitoring stack \u2014 Performance Monitor (PerfMon), Data Collector Sets, and the <code>Get-Counter<\/code> PowerShell cmdlet \u2014 that covers 95% of what a small team needs without buying an agent. The problem is rarely tooling; it is knowing which of the hundreds of counters actually predict trouble. This article lists the counters that matter on a typical IIS or SQL Server workload, gives realistic thresholds, and shows how to build a scheduled Data Collector Set with alerting so you hear about problems before users do. It assumes a standard Windows Server VPS; the <a href=\"https:\/\/windows-vps.org\/\">Windows VPS hosting<\/a> guides on this site cover the base setup these checks assume.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The counters that actually matter<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Most counters are noise. The shortlist below has caught real incidents \u2014 runaway loops, memory leaks, disk saturation \u2014 on every server I have monitored. Thresholds are for a 2\u20134 vCPU \/ 4\u20138 GB box; scale the queue-length rules by core count.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Counter<\/th><th>Warning threshold<\/th><th>What it really tells you<\/th><\/tr><\/thead><tbody><tr><td><code>Processor\\% Processor Time<\/code> (_Total)<\/td><td>&gt; 85% sustained<\/td><td>CPU saturation; check System\\Processor Queue Length to confirm<\/td><\/tr><tr><td><code>System\\Processor Queue Length<\/code><\/td><td>&gt; 2 per core<\/td><td>Threads waiting for CPU \u2014 classic oversubscription sign<\/td><\/tr><tr><td><code>Memory\\Available MBytes<\/code><\/td><td>&lt; 10% of total RAM<\/td><td>Memory pressure; pages\/sec spikes usually follow<\/td><\/tr><tr><td><code>Memory\\Pages\/sec<\/code><\/td><td>&gt; 1,000 sustained<\/td><td>Heavy paging \u2014 disk is now your RAM<\/td><\/tr><tr><td><code>PhysicalDisk\\Avg. Disk sec\/Read<\/code><\/td><td>&gt; 20 ms<\/td><td>Slow reads; on NVMe anything above ~5 ms is suspicious<\/td><\/tr><tr><td><code>PhysicalDisk\\Avg. Disk sec\/Write<\/code><\/td><td>&gt; 20 ms<\/td><td>Write latency; check for backup jobs overlapping traffic<\/td><\/tr><tr><td><code>PhysicalDisk\\Current Disk Queue Length<\/code><\/td><td>&gt; 2 per disk<\/td><td>Requests stacking up; correlate with latency before acting<\/td><\/tr><tr><td><code>Network Interface\\Bytes Total\/sec<\/code><\/td><td>&gt; 80% of NIC speed<\/td><td>Bandwidth ceiling; relevant on 1 Gbps VPS NICs<\/td><\/tr><tr><td><code>Process\\Working Set<\/code> (per w3wp\/sqlservr)<\/td><td>Growth over 24 h<\/td><td>Leak detection \u2014 trend, not threshold<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">One caution: <code>% Processor Time<\/code> above 85% is only actionable when the processor queue is also high. A single core pegged at 100% on a four-core box shows 25% total \u2014 check the per-instance counters (<code>Processor(1)\\% Processor Time<\/code>) to find a stuck thread.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Quick checks with Get-Counter<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before building anything persistent, run these one-liners to get a baseline:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Get-Counter '\\Processor(_Total)\\% Processor Time','\\Memory\\Available MBytes','\\PhysicalDisk(_Total)\\Avg. Disk sec\/Read','\\PhysicalDisk(_Total)\\Avg. Disk sec\/Write' -SampleInterval 1 -MaxSamples 5<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And the leak check \u2014 working set of the top five processes by memory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 5 Name, @{n='WorkingSetMB';e={[math]::Round($_.WorkingSet64\/1MB)}}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Run these three times a day for a week and note the normal range. Thresholds are only meaningful relative to your baseline \u2014 a server that always idles at 60% CPU is different from one spiking from 10% to 60% at the same hour every day.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Build a Data Collector Set<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Data Collector Sets are PerfMon&#8217;s way of logging counters to disk on a schedule. To create one for the shortlist above from an elevated prompt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>logman create counter ServerHealth -f bincirc -max 1024 -si 00:00:30 `\n  -c \"\\Processor(_Total)\\% Processor Time\" \"\\System\\Processor Queue Length\" `\n     \"\\Memory\\Available MBytes\" \"\\Memory\\Pages\/sec\" `\n     \"\\PhysicalDisk(_Total)\\Avg. Disk sec\/Read\" \"\\PhysicalDisk(_Total)\\Avg. Disk sec\/Write\" `\n     \"\\PhysicalDisk(_Total)\\Current Disk Queue Length\" \"\\Network Interface(*)\\Bytes Total\/sec\"\nlogman start ServerHealth<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This logs every 30 seconds into a circular 1 GB file. To make it survive reboots, register it as a scheduled task: <code>logman create ... <\/code> then <code>schtasks \/create \/tn \"ServerHealth\" \/tr \"logman start ServerHealth\" \/sc onstart<\/code>. The <code>bincirc<\/code> format is compact and PerfMon reads it natively; convert to CSV later with <code>relog<\/code> if you want it in Excel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Turn the log into an alert<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A log nobody reads is just a bigger disk problem. The built-in alerting path is: PerfMon alerts that fire a scheduled task. First create an alert Data Collector Set:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>logman create alert CPUAlert -th \"\\Processor(_Total)\\% Processor Time&gt;85\" -si 00:01:00\nlogman start CPUAlert<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then attach an action. The cleanest no-code option: in the alert&#8217;s properties (Performance Monitor \u2192 Data Collector Sets \u2192 User Defined \u2192 CPUAlert \u2192 right-click \u2192 Properties \u2192 Alerts tab \u2192 Task), point it at a scheduled task that sends email or writes to the Application log. With no mail server handy, have the task run PowerShell that writes an event:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>logman create alert CPUAlert -th \"\\Processor(_Total)\\% Processor Time&gt;85\" -si 00:01:00 -tn \"CPUAlertAction\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And the action task:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>schtasks \/create \/tn CPUAlertAction \/tr \"powershell -Command Write-EventLog -LogName Application -Source PerfMon -EventId 9001 -EntryType Warning -Message 'CPU above 85%% for 1 minute'\" \/sc once \/st 00:00 \/ru SYSTEM \/f<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Whatever action you choose, alert on the <em>sustained<\/em> condition, not a single sample. A 5-second compile spike on a build server will page you into oblivion if you alert on any reading above 85%; the 1-minute sample interval above is a reasonable compromise.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Reading the results<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">After a few days, convert the binary log and look for patterns rather than peaks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>relog ServerHealth_000001.blg -f csv -o health.csv\nImport-Csv health.csv | Group-Object { ([datetime]$_.Timestamp).Hour } |\n  ForEach-Object { [pscustomobject]@{ Hour=$_.Name; AvgCPU=($_.Group.'\\\\machine\\processor(_total)\\% processor time' | Measure-Object -Average).Average } }<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Hourly averages instantly reveal the daily shape: the 02:00 backup spike, the 09:00 login rush, the 17:00 batch job. Compare the same hour across days \u2014 that is where slow leaks and creeping baselines show up. If <code>Avg. Disk sec\/Read<\/code> climbs by 2 ms every day for a week while the workload is flat, the disk is degrading; that is the signal to move the database file or open a ticket with your provider before it fails outright.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">When to graduate to real monitoring<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">PerfMon covers capacity and health, but it will not tell you that a specific HTTP endpoint is returning 500s or that TLS certificates are expiring. Once your infrastructure outgrows a single box \u2014 multiple servers, a load balancer, a team that needs a shared dashboard \u2014 a proper monitoring stack (Prometheus\/Grafana or a SaaS agent) earns its keep. Until then, the counters above, a scheduled Data Collector Set, and one alert catch the incidents that actually hurt. If you are standing up a new server to monitor, <a href=\"https:\/\/windows-vps.org\/\">our Windows VPS plans<\/a> include enough CPU and RAM headroom for PerfMon logging without disturbing your application.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Windows Server ships with a full performance-monitoring stack \u2014 Performance Monitor (PerfMon), Data Collector Sets, and the Get-Counter PowerShell cmdlet \u2014 that covers 95% of what a small team needs without buying an agent. The problem is rarely tooling; it is knowing which of the hundreds of counters actually predict trouble. This article lists the &#8230; <a title=\"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter\" class=\"read-more\" href=\"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/\" aria-label=\"Read more about Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":2,"footnotes":""},"categories":[5],"tags":[],"class_list":["post-625","post","type-post","status-publish","format-standard","hentry","category-tutorials-guides"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter - Windows VPS Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter\" \/>\n<meta property=\"og:description\" content=\"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter\" \/>\n<meta property=\"og:url\" content=\"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/\" \/>\n<meta property=\"og:site_name\" content=\"Windows VPS Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-14T23:08:03+00:00\" \/>\n<meta name=\"author\" content=\"windows-vps\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"windows-vps\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/\",\"url\":\"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/\",\"name\":\"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter - Windows VPS Blog\",\"isPartOf\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/#website\"},\"datePublished\":\"2026-08-14T23:08:03+00:00\",\"author\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58\"},\"breadcrumb\":{\"@id\":\"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/windows-vps.org\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/windows-vps.org\/blog\/#website\",\"url\":\"https:\/\/windows-vps.org\/blog\/\",\"name\":\"Windows VPS Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/windows-vps.org\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58\",\"name\":\"windows-vps\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g\",\"caption\":\"windows-vps\"},\"sameAs\":[\"https:\/\/windows-vps.org\/blog\"],\"url\":\"https:\/\/windows-vps.org\/blog\/author\/myxiechengxuan\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter - Windows VPS Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/","og_locale":"en_US","og_type":"article","og_title":"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter","og_description":"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter","og_url":"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/","og_site_name":"Windows VPS Blog","article_published_time":"2026-08-14T23:08:03+00:00","author":"windows-vps","twitter_card":"summary_large_image","twitter_misc":{"Written by":"windows-vps","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/","url":"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/","name":"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter - Windows VPS Blog","isPartOf":{"@id":"https:\/\/windows-vps.org\/blog\/#website"},"datePublished":"2026-08-14T23:08:03+00:00","author":{"@id":"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58"},"breadcrumb":{"@id":"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/windows-vps.org\/blog\/windows-server-performance-monitoring-perfmon-counters\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/windows-vps.org\/blog\/"},{"@type":"ListItem","position":2,"name":"Windows Server Performance Monitoring: PerfMon Counters and Alerts That Actually Matter"}]},{"@type":"WebSite","@id":"https:\/\/windows-vps.org\/blog\/#website","url":"https:\/\/windows-vps.org\/blog\/","name":"Windows VPS Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/windows-vps.org\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/44caceed916d0db318aa08d5623a7a58","name":"windows-vps","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/windows-vps.org\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3f2573db5afcd1a6ab9abcc5d48fc8e42584bc87ab9d98cc156e5b2097766dd9?s=96&d=mm&r=g","caption":"windows-vps"},"sameAs":["https:\/\/windows-vps.org\/blog"],"url":"https:\/\/windows-vps.org\/blog\/author\/myxiechengxuan\/"}]}},"_links":{"self":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/625","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/comments?post=625"}],"version-history":[{"count":1,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/625\/revisions"}],"predecessor-version":[{"id":626,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/posts\/625\/revisions\/626"}],"wp:attachment":[{"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/media?parent=625"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/categories?post=625"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/windows-vps.org\/blog\/wp-json\/wp\/v2\/tags?post=625"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}