pingdotgg / pingdotgg/t3code

Windows: idle app makes the whole PC unusable, background git spawns stall the desktop 25% of the time

Open
#12,498 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

accepted bug via-triage
Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

What happened

This is critical for me: T3 Code makes my whole PC unusable while it is open. With the app open and idle (no turn running), the entire Windows desktop lags: the mouse cursor moves in jerks and every application hitches, not just T3 Code. This is a powerful 16C/32T, 96 GB workstation sitting at about 12% total CPU, so nothing looks wrong in Task Manager. Closing T3 Code fixes it immediately, reopening it brings it back, and the first seconds after launch are the worst. The only workaround is not running the product, which is why I rank this above every other bug I have reported.

Diagnosis

The idle server starts 19 to 44 processes per second, all console programs (git.exe, a conhost.exe for each, taskkill.exe, gh.exe). Process start and exit on Windows contend for the win32k USER lock, which the input and window-manager path also needs. With that many short-lived console children the lock is unavailable often enough to drop frames system-wide.

A/B, same machine, same evening, only T3 Code closed in between (60 s probe each, probe in the repro section; the process rates were measured back to back):

app open, idle app closed
new processes on the machine 24.5/s 0.3/s
wall-clock time with the lock stalled 25.3% 0.5%
FindWindowW calls stalled over 4 ms 21.1% 0.3%
FindWindowW p99 16.2 ms 0.6 ms
control syscall p99 0.003 ms 0.002 ms

Same probe correlated with ETW process start/exit events, a separate 60 s run with the app open, in 100 ms buckets:

process events in bucket buckets worst FindWindowW latency (median) control syscall (median)
0 193 0.13 ms 0.001 ms
1-4 129 13.8 ms 0.001 ms
5-14 259 14.9 ms 0.002 ms
15+ 19 15.3 ms 0.002 ms
  • The control syscall never slows down (max 0.14 ms), so this is lock contention, not CPU starvation.
  • In that run 19% of calls stalled for more than 4 ms, 14.6 s of the 60 s in total (24%, matching the A/B run), each stall 15-19 ms: two to three dropped frames at 143 Hz, every time. 68% of all buckets contained at least one process event.
  • 10.7% of all busy CPU time on the machine was git.exe + conhost.exe inside win32kfull.sys.

Where the processes come from. A 20 s ETW trace counted 876 process starts (44/s); a 120 s count gave 2,258. The server's own children in those 20 s were 236 git, 26 taskkill and 11 gh; everything else is multiplication on top of that:

source tracked in share of the 876 starts
git command volume: PR sweeps, remote status, per-project identity probes #11220, #8949 236 direct git spawns, the driver of everything below
Git\cmd\git.exe launcher starts a second git.exe per command #11221 +236
a conhost.exe per console child #2537 roughly one per server spawn, ~270
taskkill /T /F on non-zero exits, each going through WMI #2537 26, plus WmiPrvSE.exe at 7.4% of busy CPU
git-credential-manager, sh, git-remote-https under fetches #11220 the remainder

The server also performs ~4,500 file opens per second resolving git on PATH before every spawn (#11221), and Defender follows all of it (7.7% of busy CPU).

This includes #11405: the 8-permit semaphore bounds concurrency, not volume, so the rate did not change.

It also amplifies any other system problem. Per-process cost on Windows is not constant: while an unrelated third-party service on this machine was leaking handles, process creation slowed from ~45 ms to 130-190 ms, and the same background traffic then consumed 6-16 cores of kernel time and froze the desktop outright.

Steps to reproduce
  1. Windows 11, Git for Windows installed the default way, desktop app with a few dozen projects (34 here, 46 threads). Leave it idle.
  2. Run the probe below for 60 s with the app open, then again with the app fully closed (tray included).
  3. Compare the stalled line and the process start rate.

Expected: an idle app is close to invisible to the rest of the machine. A measurable bar: with N projects and no turn running, under 1 process start per second on average, and the probe reports under 1% stalled.
Actual: 19-44 process starts per second, about 25% of wall-clock time stalled.

win32k-probe.ps1 (no admin, no dependencies, changes nothing)
param([int]$Seconds = 60)
Add-Type -TypeDefinition @'
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; using System.Collections.Generic;
public static class Win32kProbe {
  [DllImport("user32.dll", CharSet=CharSet.Unicode)] static extern IntPtr FindWindowW(string cls, string name);
  [DllImport("ntdll.dll")] static extern int NtQueryTimerResolution(out uint a, out uint b, out uint c);
  public static List<double[]> Run(int seconds) {
    var rows = new List<double[]>(); Thread.CurrentThread.Priority = ThreadPriority.Highest;
    double ms = 1000.0 / Stopwatch.Frequency; long end = Stopwatch.GetTimestamp() + (long)seconds * Stopwatch.Frequency; uint a, b, c;
    while (Stopwatch.GetTimestamp() < end) {
      long t0 = Stopwatch.GetTimestamp(); FindWindowW("NoSuchClass_probe", null);
      long t1 = Stopwatch.GetTimestamp(); NtQueryTimerResolution(out a, out b, out c);
      long t2 = Stopwatch.GetTimestamp();
      rows.Add(new double[] { (t1 - t0) * ms, (t2 - t1) * ms }); Thread.Sleep(1);
    }
    return rows;
  }
}
'@
$rows = [Win32kProbe]::Run($Seconds)
$u = $rows | % { $_[0] } | Sort-Object; $c = $rows | % { $_[1] } | Sort-Object
$stalls = @($u | ? { $_ -gt 4 }); $stalledMs = ($stalls | Measure-Object -Sum).Sum
"win32k call ms:  p50={0:N3}  p99={1:N2}  max={2:N2}" -f $u[[int]($u.Count*.5)], $u[[int]($u.Count*.99)], $u[-1]
"control call ms: p50={0:N3}  p99={1:N3}  max={2:N2}" -f $c[[int]($c.Count*.5)], $c[[int]($c.Count*.99)], $c[-1]
"stalls over 4 ms: {0} ({1:N1}% of calls), stalled {2:N1} s of {3} s = {4:N1}%" -f $stalls.Count, (100*$stalls.Count/$u.Count), ($stalledMs/1000), $Seconds, ($stalledMs/10/$Seconds)
Version

0.0.43-nightly.20260917.1851 (desktop). Relevant code unchanged on main @ 4d36142c02.

Environment

Windows 11 Pro 26200, 16C/32T, 96 GB, 143 Hz display, Defender real-time protection on, git 2.55 for Windows.

Evidence
OPEN:   24.5 new processes/s | stalls over 4 ms: 1313 (21.1% of calls), stalled 15.2 s of 60 s = 25.3%
CLOSED:  0.3 new processes/s | stalls over 4 ms:   26 ( 0.3% of calls), stalled  0.3 s of 60 s =  0.5%

busy CPU share, 30 s profile: git.exe 15.9%, conhost.exe 8.6%, WmiPrvSE.exe 7.4%,
  server 4.6%, git-credential-manager 2.4%, taskkill 1.5%, gh 1.3%
Related issues

#11220, #8949, #11221 and #2537 each track one cause in the code. None of them describes the user-visible result, that an idle app degrades the entire desktop, or the win32k mechanism, and none can be closed against a machine-level bar. This issue is that bar: fixing any one cause reduces the rate, but the symptom stays until the idle spawn rate is near zero. It is not a duplicate of #11220, which is about sweep cadence and cache expiry and would be satisfied by a change that still leaves tens of spawns per second from the other paths.

Fix applied or workaround

Closing T3 Code. Nothing was changed on the machine.

Filed by

Claude Code (Claude Fable 5.1), following the t3 triage playbook.

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 reproducing the idle process-start and win32k stall measurements with the supplied win32k-probe.ps1 on Windows. Trace the idle server spawn paths covered by #11220, #8949, #11221 and #2537; done means reducing idle activity below 1 process start per second and below 1% stalled in the probe.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, powershell, typescript
Domain
desktop-dev, devtools, operating-systems, performance
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.