How to monitor RAM and CPU on Windows VPS without paid tools
Practical guide to monitor RAM and CPU on a Windows VPS using Task Manager, Resource Monitor, PerfMon and PowerShell — without installing anything paid.
A Windows Server VPS consumes RAM and CPU differently than Linux — the OS overhead is larger, the pagefile is more aggressive, and GUI processes stay resident even when nobody is connected via RDP. For an admin who needs to diagnose slowness or plan a plan upgrade, knowing which native tool to use in each situation saves hours of debugging.
This guide covers the four native Windows Server tools to monitor RAM and CPU: Task Manager for immediate diagnosis, Resource Monitor for 60-second analysis with graphs, Performance Monitor for persistent historical collection, and PowerShell for automation and Server Core. None of them require an extra license, an agent install or a cloud account.
Estimated execution time: 25 to 35 minutes to set up every tool and record the first Data Collector Set with real data.
Prerequisites
You need Windows Server 2019, 2022 or 2025 with RDP access using a local or domain administrator account. PowerShell 5.1 or later ships by default. For Server Core, connect via WinRM or the direct console. Around 200 MB of free disk space if you plan to enable persistent Data Collector Sets.
Windows Server 2022 3389 5.1 Administrator Task Manager for immediate diagnosis
Task Manager is the first stop when something is visibly wrong — slow RDP, an app freezing, an external monitoring alert. In three clicks you see who is consuming what.
Connect via RDP and open Task Manager with Ctrl+Shift+Esc. If the compact version appears, click “More details” in the bottom-left corner to expand it.
Switch to the “Performance” tab — you will see real-time graphs for CPU, Memory, Disk and Ethernet. Click “Memory” to see RAM details.
Identify the numbers that matter on the memory pane:
- In use: physical RAM currently held by processes.
- Available: free RAM + standby (cache that can be reclaimed).
- Committed: total reserved including pagefile, in the “current/max” format.
- Cached: standby data that can be discarded if another process needs it.
If “Committed” is close to the max, the system is leaning hard on the pagefile. Add RAM or identify the process leaking memory.
Switch to the “Details” tab and click the “Memory (private working set)” column header to sort from largest to smallest. The top 5 processes account for 80% of consumption on most servers.
For CPU, sort by the “CPU” column — but be aware: the displayed value is instantaneous and fluctuates heavily. For a reliable average, use Resource Monitor.
The “Memory (private working set)” column shows only RAM exclusive to the process. The “Memory (shared working set)” column shows shared DLLs. To gauge real impact, look at private — that is what would disappear if you killed the process.
Resource Monitor for 60-second analysis
Resource Monitor (resmon.exe) gives a detailed view with rolling graphs of the last 60 seconds. Use it when Task Manager showed something high but you need to understand the pattern.
Press Win+R, type resmon and hit Enter. The window has 5 tabs: Overview, CPU, Memory, Disk, Network. The graphs on the right refresh every second.
Switch to the “Memory” tab. You will see processes sorted by usage, with Commit, Working Set, Shareable and Private columns. The difference compared to Task Manager is the bottom graph — “Used Physical Memory” shows hardware as a horizontal bar: Hardware Reserved, In Use, Modified, Standby and Free.
To investigate CPU, switch to the “CPU” tab. Tick the checkbox of a process in the list — the “Associated Modules” panel shows which DLLs it is executing, and “Associated Handles” lists files and registry keys it has open.
This cross-reference reveals things Task Manager does not: for example, a w3wp.exe (IIS) burning CPU because it is blocked on a log file another process left locked.
The percentage shown in “Maximum Frequency” in Resource Monitor can exceed 100% if the CPU has Turbo Boost active. On a VPS this can appear even without real Turbo, depending on how virtualization exposes the cores. Use ”% CPU Usage” as your main reference instead.
Performance Monitor for persistent history
Resource Monitor only shows 60 seconds and loses everything when closed. To track RAM and CPU consumption over hours, days or weeks, set up Data Collector Sets in Performance Monitor.
Open Performance Monitor (perfmon.exe). In the left pane, expand “Data Collector Sets” → “User Defined”. Right-click → New → Data Collector Set.
Name: RAM_CPU_Baseline. Select “Create manually (Advanced)” and click Next. Tick “Performance counter” and Next.
Under “Performance counters”, click Add and select these essential counters:
\Processor(_Total)\% Processor Time
\Memory\Available MBytes
\Memory\Committed Bytes
\Memory\Pages/sec
\Memory\Page Faults/sec
\Process(*)\Working Set
\Process(*)\% Processor Time
\System\Processor Queue LengthSet “Sample interval” to 15 seconds. In production, 60 seconds is enough — intervals that are too short generate huge files without gaining precision.
Pick the output directory (default %systemdrive%\PerfLogs\Admin\RAM_CPU_Baseline). Click Finish. Right-click the new Data Collector Set → Start. Collection begins immediately in the binary .blg format.
To stop after a few hours, right-click → Stop. The file appears under “Reports” → “User Defined” → your set. Double-click to open the historical graph.
To open the data in Excel or pipe it into an analytics stack, convert the .blg to CSV: relog C:\PerfLogs\Admin\RAM_CPU_Baseline\DataCollector01.blg -f CSV -o output.csv. The relog command ships with Windows Server — nothing to install.
PowerShell for automation and Server Core
Windows Server Core has no GUI — PowerShell is the only option. Even on Server with GUI, scripts are useful to collect metrics across multiple servers at once or to ship them to an external endpoint.
For a quick snapshot of RAM and CPU right now, run in PowerShell:
Get-CimInstance Win32_OperatingSystem | Select-Object `
@{N='RAM_Total_GB';E={[math]::Round($_.TotalVisibleMemorySize/1MB,2)}}, `
@{N='RAM_Free_GB';E={[math]::Round($_.FreePhysicalMemory/1MB,2)}}, `
@{N='RAM_Used_Pct';E={[math]::Round((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory) / $_.TotalVisibleMemorySize) * 100, 2)}}
Get-CimInstance Win32_Processor | Select-Object Name, LoadPercentageThe result shows total RAM, free RAM and usage percentage, plus the average CPU load at the moment.
To identify the top 10 RAM-consuming processes, sorted:
Get-Process | Sort-Object WorkingSet64 -Descending |
Select-Object -First 10 `
Name, Id, `
@{N='RAM_MB';E={[math]::Round($_.WorkingSet64/1MB,2)}}, `
@{N='CPU_sec';E={[math]::Round($_.CPU,2)}} |
Format-Table -AutoSizeThe CPU field shows total CPU seconds consumed by the process since it started — useful to spot long-running processes that have accumulated load.
For continuous monitoring every 30 seconds, save this script as monitor.ps1:
while ($true) {
$ts = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
$cpu = (Get-CimInstance Win32_Processor).LoadPercentage
$os = Get-CimInstance Win32_OperatingSystem
$ramPct = [math]::Round((($os.TotalVisibleMemorySize - $os.FreePhysicalMemory) / $os.TotalVisibleMemorySize) * 100, 2)
"$ts CPU=$cpu% RAM=$ramPct%" | Out-File -Append C:\PerfLogs\monitor.log
Start-Sleep -Seconds 30
}Run it in the background: Start-Process powershell -ArgumentList "-File C:\scripts\monitor.ps1" -WindowStyle Hidden. The log stays in a simple format, easy to parse with Get-Content later.
Verification
To confirm each tool is collecting data correctly:
# Confirm the Data Collector Set is running
logman query RAM_CPU_Baseline
# List the .blg files generated
Get-ChildItem C:\PerfLogs\Admin\RAM_CPU_Baseline\ -Recurse -Filter *.blg
# Confirm monitor.ps1 is writing
Get-Content C:\PerfLogs\monitor.log -Tail 5
Expected output: logman query should show Status: Running, there should be at least one .blg in the directory (even if small), and the PowerShell log should show recent lines with timestamps from the last few minutes.
Troubleshooting
Performance Monitor does not create the .blg file
Check permissions on the output folder. The “SYSTEM” user needs write access to C:\PerfLogs. Run icacls C:\PerfLogs — if SYSTEM is missing the (F) flag, fix it with icacls C:\PerfLogs /grant SYSTEM:F /T. Also confirm the disk has at least 500 MB free, otherwise the collector stops silently.
Get-Counter returns “Path could not be found”
This happens when the system runs in another language (Portuguese, Spanish) and the counters appear with translated names. Use the numeric syntax instead of the textual one: (Get-Counter '\2\6').CounterSamples.CookedValue returns ”% Processor Time” regardless of language. The full ID list lives at HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Counter.
Resource Monitor shows the “System” process consuming lots of RAM
The System process (PID 4) with a large working set usually points to a driver leaking memory or aggressive filesystem cache. Use poolmon.exe (part of the Windows Driver Kit) to see which pool tag is growing. On a VPS, it is common for paravirtualization drivers (network or disk) to need an update.
Next steps
With the four tools under your belt, you have full monitoring coverage at no extra cost. To go further:
- Configure alerts in Performance Monitor (right-click the Data Collector Set → Properties → Alerts) to fire when available RAM drops below 500 MB.
- Use WMI Events in PowerShell for automatic actions — restart a service when CPU stays above 90% for more than 5 minutes.
- Centralize logs from multiple servers into a single station via Event Forwarding or Windows Admin Center.
- Study the Memory\Pool Paged Bytes and Pool Nonpaged Bytes counters to detect kernel leaks early.
If you are provisioning Windows environments for production, a Hostini VPS on a plan tuned for Windows Server already comes with dedicated RAM (no oversubscription), which makes Available MBytes and Committed Bytes readings trustworthy — on oversubscribed environments, the guest numbers can lie.
Frequently asked questions
What is the difference between Memory In Use and Committed in Task Manager?
In Use is the physical RAM actively held by processes right now. Committed is the sum of physical RAM plus pagefile reserved by the system — it can exceed total RAM because it includes virtual memory. If Committed grows above 1.5x physical RAM, the server is doing heavy paging and the CPU will suffer from disk I/O.
Why does CPU usage in Task Manager differ from Resource Monitor?
Task Manager shows average utilization across the refresh interval (1-2s), while Resource Monitor shows per-core averages over the last 60 seconds with a graph. Under spiky load, Task Manager can flash 100% momentarily, while Resource Monitor smooths it out. For debugging stuck processes, use Resource Monitor — the historical graph reveals patterns.
Can I run Performance Monitor without impacting production?
Yes — PerfMon counters have minimal overhead (<1% CPU) when collected at intervals of 15s or longer. The cost shows up when you log hundreds of counters every 1 second. For production, configure Data Collector Sets with a 60s interval and keep only the 8-10 counters that actually matter for your case.
How do I see which process is consuming RAM on Windows Server Core?
Without a GUI, use PowerShell: Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 10 Name, Id, @{N='RAM_MB';E={[math]::Round($_.WorkingSet64/1MB,2)}}. WorkingSet64 shows real physical RAM, unlike PrivateMemorySize which includes pagefile. For CPU, swap WorkingSet64 for CPU.
Available MBytes is high but the server feels slow. Why?
High available RAM with a slow system usually points to disk or CPU pressure, not memory. Check Disk Queue Length (should stay below 2) and Processor Time. Another cause is an undersized working set — Windows may be aggressively trimming pages that processes need again moments later, generating constant page faults even with free RAM.
How much history does Resource Monitor keep?
Resource Monitor shows the last 60 seconds in real time and persists nothing after you close it. For hours, days or weeks of history, configure a Data Collector Set in PerfMon with .blg output — it writes to disk and you review it later in PerfMon itself or export to CSV via relog.exe.