Run DevThrottle on Windows

5 min read

Windows is a good machine for running coding agents, and it is the machine a Gateway you host yourself runs on. But Windows ships tuned for a person who starts a few programs an hour. A fleet of agents starts dozens of small programs a minute - every command an agent runs, and every hook around it, is a new process. That workload finds problems ordinary use never does. This page lists the settings that keep a Windows machine healthy under a fleet: what goes wrong, the fix, how to check it, and what the fix costs.

Note
For coding agents reading this page: every step below is a PowerShell command you can run. One step must run in a visible window on the desktop, not inside your own terminal session - it says so where it matters, and shows how to open that window yourself.

1. The token leak in Windows 11 version 25H2

What goes wrong

Every program Windows starts gets a security token - a small piece of kernel memory that says who the program runs as, like an ID badge. When the program exits, Windows should free the token. Windows 11 version 25H2 (build 26200) has a bug: when it checks whether a newly started console program may bring its window to the front, it takes a reference to that program's token and never lets go. The token is never freed.

Most people never notice. A fleet does. On our own machine, after 19 days of agent work, Windows held 7.9 million leaked tokens and 37 GB of kernel memory, and every program launch took about 2.4 seconds. After a fresh restart without the fix, the same machine reached 11 GB in 28 hours, with the processors near 100% and almost half of that time spent inside Windows itself.

This is a Windows bug, not a DevThrottle bug, and it is not specific to any one coding agent - it is reported by other tools that start many console programs (for example git-for-windows issues 6471 and 6499). At the time of writing no Windows update fixes it.

Do you have it?

You are exposed if you run Windows 11 version 25H2 (build 26200.x). Check the build, and how much kernel paged pool memory is in use:

PowerShell
[System.Environment]::OSVersion.Version          # Build 26200 = version 25H2
"{0:N1} GB kernel paged pool" -f ((Get-Counter '\Memory\Pool Paged Bytes').CounterSamples[0].CookedValue / 1GB)

A healthy machine sits well under 1 GB of paged pool. Several gigabytes that keep growing, on a machine that has been up a day or two, is the leak. The signs you feel are a slow machine, slow program starts, and high processor use that no single program in Task Manager accounts for.

The fix: one Windows setting

The setting is the foreground lock timeout: how long Windows waits before it lets a program take focus away from the window you are using. Set to 0, Windows skips the step that holds on to the token, and the leak stops. On our machine it went from 43 to 182 leaked tokens every two minutes down to almost none. It changes no files and installs nothing.

Save this as set-foreground-timeout.ps1 somewhere permanent:

set-foreground-timeout.ps1
# Stops the Windows 11 25H2 token leak by setting the live foreground lock timeout to 0.
# Windows resets the live value at every sign-in, so this runs again at each logon.
$log = Join-Path $PSScriptRoot "set-foreground-timeout.log"
Add-Type -Name Spi -Namespace FgFix -MemberDefinition @"
[DllImport("user32.dll")] public static extern bool SystemParametersInfo(uint a, uint b, IntPtr c, uint d);
[DllImport("user32.dll", EntryPoint="SystemParametersInfo")] public static extern bool Get(uint a, uint b, ref uint c, uint d);
"@
Set-ItemProperty 'HKCU:\Control Panel\Desktop' -Name ForegroundLockTimeout -Value 0 -Type DWord
$v = [uint32]1
for ($i = 1; $i -le 10; $i++) {
  [void][FgFix.Spi]::SystemParametersInfo(0x2001, 0, [IntPtr]::Zero, 3)   # set to 0
  [void][FgFix.Spi]::Get(0x2000, 0, [ref]$v, 0)                           # read it back
  if ($v -eq 0) { break }
  Start-Sleep -Seconds 3
}
$stamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
if ($v -eq 0) { Add-Content $log "$stamp OK: live ForegroundLockTimeout = 0" }
else { Add-Content $log "$stamp FAILED: live value still $v - run this again from a visible window"; exit 1 }
Warning
It must run in a visible window on the desktop. Windows only accepts this setting from a program that is allowed to come to the front. Run from inside an agent's terminal, a background service, or a hidden window, it fails and the log says FAILED. Setting only the registry value is not enough either - the registry says 0 while the live setting Windows actually uses stays at its maximum.

A person runs it from an ordinary PowerShell window. A coding agent opens a visible window for it, which Windows does let come to the front:

PowerShell (from an agent's session)
Start-Process powershell.exe -WindowStyle Normal -Wait -ArgumentList '-NoProfile','-ExecutionPolicy','Bypass','-File','C:\path\to\set-foreground-timeout.ps1'

Make it stick: run it at every sign-in

Windows puts the live value back to its maximum every time you sign in, so the fix has to run again each time. Register a task that runs the script at logon (in a PowerShell window run as administrator):

PowerShell (as administrator)
$script  = 'C:\path\to\set-foreground-timeout.ps1'
$action  = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$script`""
$trigger = New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME
$trigger.Delay = 'PT20S'
Register-ScheduledTask -TaskName 'Fix Windows token leak (foreground lock timeout)' -Action $action -Trigger $trigger -RunLevel Limited

The task can still fail on a given sign-in if another window holds the front at that moment. On our machine it worked on one sign-in and failed on the next, and the leak ran unchecked for a day before anyone looked. So the check below is not optional.

Check it after every restart

  1. Use Restart, not Shut down. Tokens that have already leaked are only freed by a restart. With Fast Startup on (the Windows default), Shut down keeps the kernel memory, leaks included.
  2. Read the last line of the log. It sits next to the script and should have an OK line timed just after your sign-in. If it says FAILED, run the script again from a visible window.
  3. Read the live value - this is the real proof, whatever the log says:
    PowerShell
    Add-Type -Name Chk -Namespace FgFix -MemberDefinition '[DllImport("user32.dll")] public static extern bool SystemParametersInfo(uint a, uint b, ref uint c, uint d);'
    $v = [uint32]1; [void][FgFix.Chk]::SystemParametersInfo(0x2000, 0, [ref]$v, 0); "live ForegroundLockTimeout = $v   (0 = fixed)"
  4. Watch the paged pool with the command above over a few hours of agent work. It should stay roughly flat.

What the fix costs

With the timeout at 0, a program can occasionally bring its window to the front while you are typing somewhere else. That is the whole cost. On a machine that mostly runs agents it is rarely noticed.

To undo it: delete the logon task, and set the value back to the Windows default with SystemParametersInfo(0x2001, 0, 2147483647, 3) (or restart, which resets it on its own once the task is gone).

Tip
The fix stops new leaks; it does not give back memory that has already leaked. If the paged pool is already several gigabytes, apply the fix now and restart when it suits you.

Where to go next

Talk to usBook a 20-minute call