Skip to content

Build Governor

The build governor prevents memory exhaustion during parallel C++ builds by monitoring commit charge and throttling compiler processes.

Each cl.exe process can use 1–4 GB of RAM. With -j16, that’s potentially 64 GB of memory demand. When commit charge hits 100%, Windows becomes unresponsive and builds fail silently.

The error you see is often STATUS_STACK_BUFFER_OVERRUN (0xC0000409), which is misleading — the real cause is std::bad_alloc. This happens because:

  1. Exception not caught → std::terminate() called
  2. terminate() calls abort()
  3. MSVC’s /GS security checks interpret this as a buffer overrun

The governor uses compiler wrappers that intercept cl.exe calls:

  1. You run cmake --build . --parallel 16
  2. Each cl.exe invocation hits the wrapper (in PATH)
  3. The wrapper checks if the governor is running — auto-starts it if not
  4. The wrapper requests tokens based on current commit charge
  5. The real cl.exe runs
  6. Tokens are released when compilation finishes

The governor monitors commit charge because:

  • Commit charge = promised memory (even if not yet paged in)
  • When the commit limit is reached, allocations fail immediately
  • Free RAM is misleading — file cache and standby pages inflate the number

The wrappers work with all major build systems:

Terminal window
cmake --build . --parallel 16
msbuild /m:16
ninja -j 8