Waiting 14 minutes for a Windows CI job kills developer flow. For our Model Context Protocol server (Sentinel-IR-MCP), we refused to tolerate that bottleneck anymore.
Here is exactly how we optimized our Windows test suite across Node 20, 22, and 24, dropping the total job runtime to 2 minutes and 44 seconds without sacrificing a single check.
Source (GitLab, Apache-2.0): https://gitlab.com/jakubrojicek11/sentinel-ir-mcp
Package (npm): https://www.npmjs.com/package/sentinel-ir-mcp
The analyzer behind it: https://www.npmjs.com/package/sentinel-ir
The Bottleneck (GitLab Shared Windows Runners)
A standard run on GitLab SaaS Windows took 13.6 minutes, even though our 118 unit tests executed in just 1.6 minutes. The rest was pure infrastructure drag:
⢠VM Provisioning: 3.5 minutes (unfixable)
⢠Real-time Antivirus: Windows Defender choked on npm ci and execution scripts, dragging out our compat-smoke test to 2.9 minutes.
The Fix: Strategic Split & Target Optimization
Instead of fighting the slow runner environment, we re-architected where and how the jobs run:
- Shifted Dev Push Matrices to GitHub Actions: GitHub's windows-latest images spin up in seconds (1ā2 s) instead of minutes.
- Built-in Security Clearance: Real-time scanning (RealTimeProtectionEnabled) is off by default on GitHub's native dev images. This instantly cut our compat-smoke step down to seconds.
- Smart Caching & Selective Runs: We enabled direct Node/npm caching and added strict rules to completely skip the Windows matrix if a commit only modifies the README.md.
- Kept GitLab strictly for Releases: The heavy GitLab Windows job was moved to run only on release tags as a final gate before publishing to npm.
The Result
Step (Node 24) Old GitLab Pipeline New GitHub Actions Pipeline
VM Boot / Wait ~3.5 min 1ā2 s
npm ci 84 s 4ā9 s
Test Execution 95 s 22ā28 s
Total Job Time 13.6 min 2.7 min

The code quality remains identical. All 118 tests run flawlessly across all Node versions, but now the feedback loop takes less than 3 minutes.
If your Windows pipelines are killing your productivity, look closely at VM spin-up times and real-time antivirus hooks. The performance lift is hiding right there.

Top comments (1)
The breakdown is the useful part ā most of the 13.6 minutes wasn't the tests at all, it was the 3.5-minute VM provisioning plus Defender chewing through
npm ci. Moving the dev matrix to GitHub Actions while keeping GitLab for releases only is the right split: you get the fast spin-up where you iterate, and keep the heavy runner where it actually matters. The npm ci drop from 84s to 4ā9s is the number that would convince me to try the same move.