Files
orca/docs/reference/windows-performance-tracker.md
T

13 KiB

Windows and WSL Performance Tracker

Last verified: 2026-08-08

This document is the durable queue for Windows performance work. The umbrella issue is #9300. Keep fixes measurement-first: add a deterministic reproduction, record median and p95 where timing matters, verify correctness as well as latency, and preserve native Windows, WSL, SSH, folder-workspace, and mixed-version behavior.

Status at a glance

Priority Area Tracking Status Next action
P0 WSL Git status and staging latency #9284, #9768, PR #13207 Fix PR open Land the measured shell-startup fix, then investigate DrvFS routing and linked-gitdir compatibility separately.
P1 Cross-cutting Windows/WSL measurements #9300, PR #11261 Open Establish the baseline matrix below and use interleaved comparisons for startup changes.
P1 Clipboard staging-directory ownership #12835, PR #12917 Fix merged; design follow-up unfiled Move new staging files under one Orca-owned parent so cleanup never enumerates the shared temp root.
P1 WSL hook-relay startup reconciliation #12900, PR #13139 Fix merged; design follow-up unfiled Reconcile relays once from the live daemon-session inventory after the hook server starts.
P2 Main-process child-spawn audit #11161, PR #12217, PR #11698 Known triggers fixed; audit remains Find remaining startup or periodic main-process spawns and measure event-loop gaps under injected spawn delay.
P2 Reverted accumulator protections PR #10179, PR #10255 Unscoped Audit current hot paths individually; file only narrow issues with a present-day deterministic reproduction.
Monitor General embedded-TUI lag #12446 Closed as fixed Reopen only with an exact version, agent, local/remote runtime, and captured frame/event-loop metrics.

Environment requirements:

  • Real WSL required: Git hot-path benchmarking and hook-relay startup reconciliation.
  • Native Windows sufficient: clipboard parent migration, blocking-spawn fault injection, capability probing, and startup measurements.
  • Platform-independent unit work is not a substitute for real Windows/WSL latency evidence where a subprocess or filesystem boundary is the suspected cause.

Completed fixes and evidence

Port scanning under slow process creation

  • Issue #11161, fixed by PR #12217.
  • Endpoint-security software could delay CreateProcessW; even asynchronous Node process APIs perform process creation on the caller, freezing Electron's main event loop.
  • Port-scan commands moved to a worker, command deadlines now begin after process creation, and the tests inject a real delayed spawn to pin UI responsiveness and false-timeout behavior.

Repeated WSL and PowerShell capability probes

  • Fixed by PR #11698, merge commit c3bf22b9a8.
  • Repeated synchronous wsl.exe and pwsh.exe probes could pause the main loop every 30 seconds.
  • Capability reads are asynchronous and share one bounded 30 s → 60 s → 120 s backoff, followed by a five-minute ceiling check. A stable no-WSL session drops from 60 checks per consumer in 30 minutes to at most nine shared reads.
  • Native Windows ABBA results:
Command Synchronous median / p95 event-loop gap Asynchronous median / p95 gap
wsl.exe --status 34.1 / 63.5 ms 16.1 / 16.4 ms
wsl.exe --list --quiet 35.1 / 37.3 ms 16.0 / 25.5 ms
pwsh.exe -Version 103.0 / 312.9 ms 18.9 / 25.8 ms

Startup hang while cleaning remote clipboard files

  • Issue #12835, fixed by PR #12917, merge commit 595097b5fc.
  • A temp root with 1,232,261 entries produced approximately 1.23 million promises on the main process, causing a V8 microtask and garbage-collection storm.
  • Cleanup now streams with opendir, filters foreign entries before scheduling work, and caps removals at eight. A native Windows Electron run remained responsive with 100,000 unrelated entries.

Slow Codex hooks after Orca restart

  • Issue #12900, fixed by PR #13139, merge commit 982570648a.
  • Daemon-backed WSL Codex sessions survived an Orca restart while their stable endpoint file retained the old main-process port and token. Each tool call could pay two stale-hook fallbacks.
  • A local WSL PTY reattach now ensures the relay for the daemon-reported original distro. Native, fresh, SSH, blank, and unknown-distro cases are no-ops; the manager deduplicates per distro.
  • Real Windows/WSL2 benchmark, using the generated Codex hook and production relay:
Phase Samples Median p95 Delivery
Stale endpoint 20 1,636.0 ms 1,639.1 ms timeout/fail-open
Refreshed on reattach 20 58.5 ms 61.9 ms 20/20

WSL login-shell overhead on Git reads

  • Issues #9284 and #9768, addressed by open PR #13207.
  • WSL source-control reads repeatedly started a login shell. Slow profile scripts and banner output added latency and could contaminate Git's machine-readable output.
  • The first read retains the login-shell behavior while a background per-distro probe captures Git's absolute path and PATH. Later status, numstat, and upstream/config reads execute directly. Mutations, network operations, SSH, relay, native Git, and risky profile environments stay on the existing path.
  • Real Windows 11/WSL2 ABBA results, with 3 warmups and 20 samples per natural-profile pair:
Operation Login median / p95 Direct median / p95
WSL-filesystem status 73.2 / 75.7 ms 63.5 / 66.8 ms
WSL-filesystem stage+refresh 221.1 / 234.8 ms 203.3 / 207.0 ms
DrvFS status 1,063.2 / 1,134.4 ms 1,030.8 / 1,070.5 ms
DrvFS stage+refresh 1,272.7 / 1,318.8 ms 1,225.3 / 1,246.4 ms
  • With a deterministic 250 ms login-profile delay, 2 warmups and 10 samples, native status fell from 330.1 / 339.4 ms median / p95 to 64.5 / 67.7 ms. Every benchmark pair produced byte-identical Git payloads. The profile also emitted 106 bytes of non-Git banner text per login-shell invocation.

Next investigation: WSL filesystem-host routing

PR #13207 removes avoidable shell startup but does not address the dominant cost for repositories on C:\: Git traversing the tree through WSL's DrvFS mount. In the same fixture, Windows Git completed status in 22.4 ms median versus approximately 1,031 ms through WSL/DrvFS.

Investigate whether read-only source-control operations should follow the filesystem host instead of the selected terminal runtime. First prove equivalent status semantics across Git configuration, autocrlf, symlinks, hooks, credentials, case behavior, worktree metadata, SSH/folder workspaces, and Git 2.25. Do not route mutations or network operations until their environment contract is independently established.

Windows-created linked worktrees need a separate compatibility design: their .git files can contain a C:/.../.git/worktrees/... gitdir that WSL Git cannot resolve. Path translation must be scoped to metadata owned by the routed repository and must not rewrite arbitrary Git output.

Architectural follow-ups

Own the clipboard staging parent

PR #12917 makes shared-temp enumeration memory-safe, but enumeration time is still proportional to every other application's temp entries. New transfers should use a structure such as:

<os-temp>/orca-clipboard-files/<transfer-id>/...

Cleanup could then enumerate only Orca-owned children. Preserve a bounded compatibility sweep for legacy top-level orca-clipboard-file-* directories, prove symlink and path containment, and benchmark against a large foreign temp root before removing legacy handling.

Reconcile WSL hook relays at startup

PR #13139 repairs the relay when one of today's PTY reattach paths runs. The desired-state design is:

  1. Start the new main-process hook server.
  2. Read the daemon's live local session inventory.
  3. Group authoritative non-null WSL owners by distro.
  4. Ensure and observe one relay per live distro.
  5. Retain reattach-time ensure as a safety net for later sessions.

Only live sessions should participate; cold history or stale metadata must not boot a stopped distro. Cover multiple panes in one distro, multiple distros, old daemons without WSL metadata, immediate hook traffic, relay failure, and startup ordering.

Continue the blocking-spawn audit

PRs #12217 and #11698 removed two proven main-thread freeze sources, not the entire failure class. Audit main-process spawnSync/execFileSync calls and periodic asynchronous spawns whose process creation still runs on the main thread. Prioritize startup, focus, polling, watcher, Git, and terminal-open paths. Use an injected process-creation delay and event-loop-gap measurement; do not infer responsiveness from command completion time alone.

Measurement backlog

The baseline requested by #9300 is still incomplete:

  • open worktree → first useful Git status;
  • idle child-process spawns per minute;
  • watcher installation during a worktree switch;
  • quick-open and search in a medium repository;
  • PTY spawn, separated into process creation, environment/probe work, and first usable prompt;
  • native C:\ repo, WSL-filesystem repo, and C:\ repo using a WSL project runtime;
  • Defender/default endpoint security and a controlled excluded-worktree comparison.

PR #11261 provides an open interleaved startup benchmark with drift controls. PR #11262 is a useful caution: its bundle-size change did not show the initially suspected seconds-scale startup improvement once measured interleaved. Do not quote blocked before/after startup medians when the machine itself can drift.

Triage rules

  • Attach an exact Orca version, Windows build, repository location, selected project runtime, and agent.
  • Separate UI event-loop stalls from a command that is merely slow in the background.
  • Prefer deterministic fault injection for hangs and interleaved samples for performance comparisons.
  • Report median, p95, failures/timeouts, and correctness; a faster wrong result is not a win.
  • Keep broad audits in #9300, but give every actionable root cause its own issue and narrowly scoped PR.
  • Avoid another repository-wide performance or memory mega-PR. #10179 contained useful protections, but its 1,626-file scope was reverted by #10255; re-land measured fixes independently with focused tests.