nodejs / nodejs/build

Enabling PGO for Windows releases

Open
#4,452 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

ci-release jenkins platform:windows
Dominant language
Jinja
Stars
541
Forks
185
Avg merge
22h 15m
Merged PRs (30d)
4

Description

I want to start a discussion about enabling PGO for release builds on Windows. Along with LTO (enabled since v26.3), it will further improve Node.js performance on Windows. While LTO builds took 3-3.5 hours initially, recent changes have reduced them to around 2 hours. Enabling PGO will double that time (2 builds are needed plus running workload scripts in between), but overall it will be a bit longer than what LTO took last week. Additionally, I would only enable PGO for release builds, so nightly and canary builds would be unaffected. I feel confident in enabling this because I've already tested it thoroughly in a draft job.

Since Jenkins changes are only visible after they are made, I want to share what I plan to change here before doing it. What we currently have is this:

vcbuild.bat build-release %ARCH% upload

and I would change it to this:

if not exist pgo.ps1 goto :no-pgo
if not "%DISTTYPE%"=="release" goto :no-pgo

echo === PGO Build: Step 1 - Build instrumented binary ===
@REM In first PGO build, make x64 binary to generate profdata (Eventually we want to add ARM64 machines for this)
call vcbuild.bat build-release x64 pgo-generate
if errorlevel 1 exit /b %errorlevel%

echo === PGO Build: Step 2 - Run workload and collect profiles ===
powershell -NoProfile -ExecutionPolicy Bypass -File pgo.ps1 -PgoGenNode Release\node.exe -PhaseOnly
if errorlevel 1 exit /b %errorlevel%
echo --- Cleaning instrumented build ---
git clean -fdx -e node.profdata
if errorlevel 1 exit /b %errorlevel%

echo === PGO Build: Step 3 - Build optimized binary ===
call vcbuild.bat build-release %ARCH% pgo-use upload
exit /b %errorlevel%

:no-pgo
echo === Non-PGO Build ===
vcbuild.bat build-release %ARCH% upload

The script checks whether the Node.js being built has PGO enabled, and if so, it uses it for release builds. This way, if/when we backport PGO to LTS versions, they will pick it up for releases without any further changes in Jenkins.

As I've already stated, I tested this and feel confident about enabling it, but please feel free to share any concerns you might have about these changes.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the draft Jenkins job and the current release command shown in the issue, then inspect pgo.ps1 and the vcbuild.bat PGO arguments. Confirm that release builds can complete the three PGO steps while nightly and canary builds retain the non-PGO path, using the draft job as the validation reference.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, powershell
Domain
build-system, ci-cd, release
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.