Skip to content

perf(server): fix N+1 PowerShell process query and reduce sampling frequency - #4829

Open
UtkarshUsername wants to merge 5 commits into
pingdotgg:mainfrom
UtkarshUsername:fix/perf-resource-monitor-n-plus-1
Open

perf(server): fix N+1 PowerShell process query and reduce sampling frequency#4829
UtkarshUsername wants to merge 5 commits into
pingdotgg:mainfrom
UtkarshUsername:fix/perf-resource-monitor-n-plus-1

Conversation

@UtkarshUsername

@UtkarshUsername UtkarshUsername commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

What Changed

Eliminated two sources of excessive CPU usage in the Windows process resource monitor:

  1. N+1 PowerShell CIM query to bulk query (ProcessDiagnostics.ts): The Windows process reader was querying Win32_PerfFormattedData_PerfProc_Process individually for each process via an IDProcess filter inside a ForEach-Object loop. Changed to query all perf counter data once into a hashtable, then join with the process list. Reduced from 1+N CIM queries to exactly 2.
  2. Sampling interval 5s to 15s (ProcessResourceMonitor.ts): Tripled the interval between resource samples, reducing overhead 3x while maintaining adequate granularity for multi-second bucket aggregation.

Why

On Windows machines with 200+ processes, ProcessResourceMonitor was spawning powershell.exe every 5 seconds with an N+1 WMI query pattern. Each cycle issued 1+N CIM queries (e.g., 206 queries for 205 processes). The old command consistently timed out after 60 seconds on a typical development machine, pegging CPU indefinitely.

Metric Before After Improvement
Per-query time >60s (timed out) ~2.7s ≥22x+
CIM queries per cycle 1+N (e.g., 206) 2 ~100x
Sampling interval 5s 15s 3x
Effective overhead 100% CPU (never finishes) ~18% for 2.7s ≥66x

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Low Risk
Diagnostics-only changes on Windows sampling path; behavior is coarser metrics (15s) but lower server CPU load, with no auth or data-path impact.

Overview
Reduces Windows process diagnostics overhead by fixing how PowerShell loads CPU perf data and by sampling less often.

Windows process query: readWindowsProcessRows no longer runs a filtered Win32_PerfFormattedData_PerfProc_Process CIM call inside the per-process loop. It loads all perf rows once into a hashtable keyed by IDProcess, then walks Win32_Process and joins in memory—two CIM queries per cycle instead of 1+N.

Resource monitor: SAMPLE_INTERVAL_MS moves from 5s to 15s, so the background sampler runs three times less often. Approximate CPU-second rollups use the new interval; tests now expect 6 instead of 2 for the same two-sample scenario.

Reviewed by Cursor Bugbot for commit 9d9363e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix N+1 PowerShell process query and increase sampling interval to 15s

  • Rewrites readWindowsProcessRows in ProcessDiagnostics.ts to preload all Win32_PerfFormattedData_PerfProc_Process entries into a hashtable keyed by IDProcess, eliminating a per-process WMI query.
  • Increases SAMPLE_INTERVAL_MS in ProcessResourceMonitor.ts from 5,000 ms to 15,000 ms to reduce polling overhead.
  • Behavioral Change: process CPU metrics are now refreshed every 15s instead of every 5s.

Macroscope summarized 9d9363e.

…agnostics

The readWindowsProcessRows function spawned powershell.exe with an N+1
WMI query pattern: for each process (via Get-CimInstance Win32_Process),
it queried Win32_PerfFormattedData_PerfProc_Process individually using a
-IDProcess filter. On machines with 200+ processes, this created 1+N
CIM queries per sampling cycle.

The old command timed out after 60s on a machine with ~205 processes.

Fix: query all performance counter data once into a hashtable
(IDProcess -> perf object), then join it with the process list in
PowerShell memory. This reduces 1+N queries to exactly 2 queries
regardless of process count.

Measured improvement (~205 processes):
- Old: >60s (timed out)
- New: ~2.7s average per query
- Speedup: ~22x+ per sampling cycle
The ProcessResourceMonitor was sampling process resources every 5
seconds. Combined with the PowerShell CIM query overhead, this caused
excessive CPU usage on Windows.

Increasing to 15s reduces sampling frequency by 3x while still
providing adequate granularity for the resource history visualization
(which aggregates into multi-second buckets).

Test: update cpuSecondsApprox expectation from 2 to 6 to match the new
interval (the calculation is SAMPLE_INTERVAL_MS / 1000 * cpuPercent/100,
so tripling the interval triples the per-sample approximation).
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 97fb8722-bcb4-4dfc-b5c7-48c11a50685b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Jul 29, 2026
@macroscopeapp

macroscopeapp Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved 2db1250

Performance optimization fixing N+1 PowerShell process query and reducing diagnostic sampling frequency from 5s to 15s. Self-contained changes to monitoring code with corresponding test updates.

You can customize Macroscope's approvability policy. Learn more.

@UtkarshUsername
UtkarshUsername force-pushed the fix/perf-resource-monitor-n-plus-1 branch from 8713172 to a8e541a Compare July 29, 2026 11:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant