Skip to content

[Bug]: Desktop renderer polls getLocalEnvironmentBootstraps via sync IPC ~2x/s, flooding desktop traces #19505

Closed as not planned

Description

@otavio

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/desktop

Steps to reproduce

  1. Launch T3 Code Desktop (Linux, local primary backend only, no WSL).
  2. Leave it open with the sidebar visible; no interaction needed.
  3. Count spans in ~/.t3/userdata/logs/desktop.trace.ndjson:
    jq -r .name ~/.t3/userdata/logs/desktop.trace.ndjson* | sort | uniq -c | sort -rn | head

Expected behavior

The renderer learns about desktop-local backend topology changes when they happen (or polls rarely), and an idle app writes little to the desktop trace.

Actual behavior

useDesktopLocalBootstraps (apps/web/src/connection/useDesktopLocalBootstraps.ts) polls desktopBridge.getLocalEnvironmentBootstraps() every 2 s per mounted consumer (LegacySidebar, CommandPalette). That bridge call is a synchronous IPC (ipc.handleSync) and each call runs desktop.backendConfiguration.resolvePrimaryLabel, which re-reads persisted settings just to build the label.

Each poll emits four spans (desktop.ipc.invokeSync → desktop.ipc.method → desktop.ipc.window.getLocalEnvironmentBootstraps → desktop.backendConfiguration.resolvePrimaryLabel), and getLocalEnvironmentEnabled is polled alongside it. On an idle machine this is the bulk of the desktop trace:

265437 spans total (2026-10-12T02:19Z → 2026-10-14T14:30Z)
 69900 desktop.ipc.method
 45380 desktop.ipc.invokeSync
 29963 desktop.ipc.window.getLocalEnvironmentBootstraps
 29963 desktop.backendConfiguration.resolvePrimaryLabel
 24520 desktop.ipc.invoke
 15411 desktop.ipc.localEnvironment.getEnabled

Per-second histogram of resolvePrimaryLabel calls: 14,858 one-second buckets with exactly 2 calls, i.e. a steady ~2 calls/s for as long as the window is open. The topology never changed during that time (single primary backend, no WSL).

Effects:

  • Rotated trace files fill with polling noise, crowding out useful history when debugging other problems (I hit this while investigating websocket drops).
  • Sync IPC from the renderer blocks its main thread for each round trip; cheap individually (~0.1 ms handler time) but continuous and needless.

The hook's doc comment already notes the cause: "The bridge exposes no change event, so we re-read on an interval".

Suggested fix: have the desktop push a topology-changed event (the pool already knows when instances register/unregister or bootstrap tokens rotate) and let the hook subscribe, dropping the interval. Alternatively, share one poller across consumers and/or stop tracing this hot path.

Impact

Minor bug or occasional failure

Version or commit

0.0.46-nightly.20261014.3105 (also present on main @ 7ac952c)

Environment

NixOS (Linux 7.2), T3 Code Nightly desktop, Electron 44.5.1 / Chrome 152

Logs or stack traces

$ jq -r 'select(.name=="desktop.backendConfiguration.resolvePrimaryLabel") | (.startTimeUnixNano|tonumber/1e9|floor)' desktop.trace.ndjson* \
    | sort | uniq -c | awk '{print $1}' | sort -n | uniq -c | sort -rn
  14858 2
     76 1
     37 3
     15 4

Activity

  1. juliusmarminge commented on Oct 14, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for the trace numbers. This is the same root cause tracked in #12689: the renderer polls desktop topology (getLocalEnvironmentBootstraps / getLocalEnvironmentEnabled) over synchronous IPC because the bridge has no change event. The triage there already names the 2 s useDesktopLocalBootstraps poll and calls for the same fix you suggest, a topology-changed event or async reads with a cached snapshot.

    Open PR #19300 moves the platform poll to async invoke with a cached snapshot. It doesn't touch useDesktopLocalBootstraps.ts or the per-call resolvePrimaryLabel settings read yet, so your span counts are a useful data point to add on #12689 or the PR.

    Closing as a duplicate of #12689 so it's tracked in one place.

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

    duplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions