Skip to content

🤖 perf: untrusted projects fork git 4× per executeBash from the main process #4661

Description

@ThomasK33

Found while diagnosing #4624.

Problem

In an untrusted project, every workspace.executeBash call first runs gitNoRepoAutomationEnvForLocalRepo (src/node/services/tools/bash.ts ~L920, src/node/utils/gitNoHooksEnv.ts). That function runs four git processes one after another from the Electron main process: rev-parse --git-dir, config --local --bool extensions.worktreeConfig, the local include check, and config --includes --get-regexp.

Opening a workspace fires four executeBash calls for that workspace (GitStatusStore status script, git fetch, PRStatusStore gh pr view, gh stack view). In an untrusted project that is 16 discovery forks plus 4 bash forks, instead of 4.

Each spawn blocks the main thread synchronously while the large Electron process forks. Measured with a temporary ChildProcess.prototype.spawn wrapper in perf.chatSwitch.spec.ts (host load ~30 on 32 cores): median 12.5 ms per spawn, 196 spawns / 2.4 s blocked in one run, 150 of them discovery. (The V8 CPU profile under-reports this, because signals are blocked during fork.) Those forks land inside the onChat replay's history read.

Effect on cold open (same build, perf fixture untrusted vs trusted, alternating runs, medians of 9 switches each):

metric untrusted trusted
cold-open-small server.totalMs 340.6 151.9
cold-open-small historyLockWaitMs 58.1 2.3
cold-open-small first row (store switch) 493.1 388.3

Options

  1. Run discovery in one spawn: a single sh -c script, like gitNoRepoAutomationEnvForRuntimeRepo, so 4 forks become 1 per call. No staleness, but it rewrites the fail-closed parsing. On Windows it needs Git Bash, which LocalBaseRuntime already requires for bash.
  2. Share one in-flight discovery per repo path between concurrent callers, so 16 forks become 4 per open. A caller then gets a config snapshot that started before it arrived. Discovery is already a snapshot taken before the script runs, but this is a security control, so review will focus on it.
  3. Reduce the fork cost itself (a spawn helper process), which would also help trusted projects (see the companion issue).

Prefer option 1, in its own PR. Measure with perf.chatSwitch.spec.ts after temporarily removing its trustDemoProject call.


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions