Skip to content

[Perf] Windows Hub idle: OpenClaw.Tray.WinUI pegs one CPU core continuously (~100%+), causing window-drag jank #1287

Closed as duplicate

Description

@Gubruce

Describe the bug

On Windows Hub (OpenClaw Companion) v2026.7.1-2, the OpenClaw.Tray.WinUI process idles at ~100% of one CPU core continuously (even when the window is idle and nothing is happening). This makes dragging/moving the main window noticeably janky (UI/rendering thread is busy).

Evidence (measured on this machine)

OpenClaw.Tray.WinUI (PID 7948) CPU samples, idle, window open but not being interacted with:

sample 1: +3.17s CPU in 3s wall  (≈106% of one core)
sample 2: +3.12s CPU in 3s wall  (≈104% of one core)
sample 3: +3.12s CPU in 3s wall  (≈104% of one core)

Meanwhile the OpenClaw Gateway node process is idle (~0% CPU), and overall system load is only ~10% with ~7 GB free RAM — so this is not a resource-starved machine; the WinUI app is burning a core on its own.

Expected behavior

When the window is idle (no messages streaming, no animation active), OpenClaw.Tray.WinUI CPU usage should be near 0%.

Actual behavior

The process continuously pegs one core (~100%+), causing window-drag jank and elevated power/heat.

Possible cause direction

Likely a WinUI3 rendering/layout busy-loop (animation, progress indicator, or layout-cycle) that never idles. Related work already exists in this repo: #1279 "fix(chat): coalesce Publish() bursts to prevent WinUI3 layout-cycle crash". A sustained single-core busy loop strongly suggests a render/layout effect that is scheduled unconditionally instead of only when needed.

Environment

  • OS: Windows 10 Pro 22H2 (build 19045, x64)
  • OpenClaw Companion (Windows Hub): v2026.7.1-2
  • OpenClaw Gateway: 2026.8.1 (local, loopback bind)
  • GPU: Intel UHD 630 (integrated) + virtual display adapters from remote-control software (GameViewer)

Repro

  1. Start OpenClaw Companion and let it idle (no chat activity, window visible).
  2. Observe CPU usage of OpenClaw.Tray.WinUI — it stays at ~100% of one core.
  3. Try dragging the main window — it lags/stutters.

Suggested fix

Ensure render/layout effects are only scheduled when the UI actually needs an update (e.g. coalesce/unschedule idle animations and progress updates), so the app idles at ~0% CPU when nothing is happening.

Activity

  1. added
    P2Normal priority bug or improvement with limited blast radius.
    clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.
    clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.
    impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.
    issue-rating: 🦪 silver shellfishThin issue quality; more reproduction proof or environment detail is needed.
    on Sep 2, 2026
  2. clawsweeper commented on Sep 2, 2026

    @clawsweeper

    Codex review: keeping this open for maintainer follow-up; there is still a little grit to resolve. Reviewed September 4, 2026, 12:52 AM ET / 04:52 UTC.

    Summary
    Keep open for trace-driven maintainer investigation. Two users report the same severe idle CPU symptom on the released build, and current main contains no verified fix, but source inspection cannot safely attribute it to one callback or loop.

    Reproducibility: no. high-confidence current-main reproduction is available. The released-build measurements are concrete and independently corroborated, but no current-main trace identifies the responsible work path.

    Ways to help us reproduce this

    • Add a screenshot or short recording showing the behavior.
    • Add expected vs actual behavior.

    Next step
    The symptom is credible but no concrete current-main hot path is proven, and the existing no-new-fix-PR and maintainer-review signals appropriately prevent speculative automated repair.

    Review details

    Best possible solution:

    Capture a Windows Performance Recorder or ETW trace while the default Connection page is visibly idle, identify the hot UI-thread stack, then make that exact source conditional or bounded and add focused regression coverage.

    Do we have a high-confidence way to reproduce the issue?

    No high-confidence current-main reproduction is available. The released-build measurements are concrete and independently corroborated, but no current-main trace identifies the responsible work path.

    Is this the best way to solve the issue?

    Unclear: conditional idle scheduling is the right likely direction, but copying the closed burst-update approach or disabling all timers would be unsafe without a hot-stack trace.

    AGENTS.md: found and applied where relevant.

    Remaining risk / open question:

    • A broad attempt to stop or coalesce background work could break the intentionally bounded pairing-recovery and managed-local gateway recovery paths without resolving the render-thread source.

    Codex review notes: model internal, reasoning high; reviewed against c5105ab06a2f.

    Label changes

    Label justifications:

    • P1: Repeated reports describe ordinary desktop use consuming a full CPU core and degrading window responsiveness.
    • impact:other: The supported impact is Windows desktop performance and power use, outside the more specific owned impact categories.
    Evidence reviewed

    What I checked:

    • Release-level reproduction: The report records three independent idle samples at about one CPU core, and a second user reports the same one-core behavior. Terminating the tray app removed the measured CPU contribution while the gateway and web UI remained available.
    • Default visible surface: The window manager constructs the Hub, binds application state, and navigates it to the Connection page by default, matching the reported visible-idle scenario. (src/OpenClaw.Tray.WinUI/Services/WindowManager.cs:198, c5105ab06a2f)
    • Inspected idle scheduling: The global pairing reconcile timer runs every 20 seconds, while the managed-local repair monitor awaits a five-second delay between evaluations. These are real long-lived work sources but do not establish a continuous UI-thread busy loop. (src/OpenClaw.Tray.WinUI/App.xaml.cs:671, c5105ab06a2f)
    • Connection progress is conditional: The default Connection page declares its status progress ring inactive and collapsed; code enables it only for an in-progress connection state. This rules out that specific indicator as an unconditional default-window animation, but not other WinUI rendering work. (src/OpenClaw.Tray.WinUI/Pages/ConnectionPage.xaml.cs:388, c5105ab06a2f)
    • Main and release history: The report targets v2026.7.1-2. The local history from that release to current main contains later tray changes but no identified idle-CPU repair, and current main is not contained by a release tag. (c5105ab06a2f)
    • Related pull request is distinct: fix(chat): coalesce Publish() bursts to prevent WinUI3 layout-cycle crash #1279 addressed active chat-event bursts and was closed unmerged. It does not establish a fix for sustained idle CPU use.

    Likely related people:

    • Barbara Kudiess: Raw commit bc210e0 adds src/OpenClaw.Tray.WinUI/Services/ManagedLocalGatewayAutoRepairMonitor.cs:102 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: medium; commits: bc210e048aa9; files: src/OpenClaw.Tray.WinUI/Services/ManagedLocalGatewayAutoRepairMonitor.cs)
    • Scott Hanselman: Suggested for follow-up; no historical authorship or introduction is verified. (role: unverified routing candidate; confidence: low)
    How this review workflow works
    • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
    • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
    • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
    • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
    • Maintainers can also comment @clawsweeper review to request a fresh review only.
    • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
    • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
    • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
  3. Gubruce commented on Sep 2, 2026

    @Gubruce
    Author

    Added a closing-control experiment to prove the idle CPU burn is the app itself (not the remote-control/virtual-display environment, and not the gateway):

    Before (idle, window open, no interaction):

    • OpenClaw.Tray.WinUI: ~104–106% of one core continuously (3 samples)
    • OpenClaw Gateway node process: ~0%

    After terminating OpenClaw.Tray.WinUI:

    • Process gone.
    • System CPU load dropped from ~10% to ~7% (the delta ≈ the single core that was pegged, on this 6-core/12-thread CPU).
    • The OpenClaw Gateway node process kept running (~0%) and the web UI (http://127.0.0.1:18789/) still returns HTTP 200.

    Conclusion: the idle CPU burn is caused entirely by the desktop app (OpenClaw.Tray.WinUI) itself. It is independent of the GameViewer virtual-display/remote-control software present on this machine and independent of the gateway. It reproduces with the window simply open and idle.

  4. sslnv88 commented on Sep 3, 2026

    @sslnv88

    Yes, I'm having this issue too. It keeps using one CPU core. I was about to report it and saw similar problems, so I'm giving this a thumbs‑up!

  5. added
    P1Urgent regression or broken agent/channel workflow affecting real users now.
    and removed
    P2Normal priority bug or improvement with limited blast radius.
    on Sep 4, 2026
  6. added
    clawsweeper:needs-infoClawSweeper needs more reporter information before it can verify this issue.
    issue-rating: 🦐 gold shrimpDecent issue quality, but reproduction details are still incomplete.
    and removed
    issue-rating: 🦪 silver shellfishThin issue quality; more reproduction proof or environment detail is needed.
    on Sep 4, 2026
  7. added this to the 9/30 MXC Release milestone on Sep 4, 2026
  8. Vivek-Rav commented on Sep 13, 2026

    @Vivek-Rav

    Adding data from a second machine, plus what looks like a resolution path for this issue.

    This is very likely a duplicate of #1325, and fixed in 2026.9.3.

    On 2026.7.1.0 (Windows 11 Pro 10.0.26200, Unpackaged install) I saw exactly the symptom described here: ~100% of one core sustained at idle, with the chat window never even opened, and Win32_PerfFormattedData_PerfProc_Thread putting thread 0 at 93–99%, ThreadState 2. Three concurring dotnet-stack samples put the UI thread in the same non-terminating render loop that #1325 documents:

    Reactor!Microsoft.UI.Reactor.Hosting.ReactorHostControl.RenderLoop()
    Reactor!Microsoft.UI.Reactor.Hosting.ReactorHostControl.Render()
    Reactor!Microsoft.UI.Reactor.Core.Reconciler.Update(...) / ReconcileComponent(...)
      -> OpenClawTray.Chat.ReactorChatComposer.Render()
      -> OpenClawTray.Chat.ToolCallCardRenderer.CreateFormatTemplates()
        -> OpenClawTray.LocalizationHelper.GetString()
        -> LocalizationHelper.TryGetValueAsString()
          -> ComWrappers.GetOrCreateObjectForComInstance
          -> ResourceContextRcwFactoryAttribute.CreateInstance
          -> IResourceMap.GetValue
    

    One detail that may be worth recording against #1325: that issue notes the heap was "99.7% COM callable wrappers" but treats the growth as a consequence of the loop. The stack above shows what was allocating them — LocalizationHelper.GetString builds a fresh WinRT ResourceContext RCW on every call, with no caching, and it is called once per string per render pass. A second thread was permanently in GC.RunFinalizers → WinRT.IObjectReference.Finalize(), which is the matching tell. So the loop drove the allocation rate, and the uncached localization lookup determined how expensive each iteration was. That also explains the reported coupling to transcript size: more tool-call cards means more GetString calls per pass.

    (Possibly aggravated by Unpackaged installs, where MRT Core resolution is weakest — TryGetValueAsString carries an out Exception, so it may have been throwing per lookup.)

    Evidence it is fixed: after updating to 2026.9.3 (which ships Microsoft.UI.Reactor 0.1.0-preview.14 via #1376), those frames are completely absent from fresh stack captures on the same machine — zero occurrences of LocalizationHelper, ResourceContext, or ReactorHostControl.RenderLoop across three samples.

    Caveat, stated plainly: I cannot give you a clean idle-CPU measurement for the native chat on 2026.9.3 to close this conclusively, because a separate regression in that build prevents the native chat from starting at all (the UI thread spins in InitialTailPositioner → StartBringItemIntoView and no window is ever created). I have filed that separately as #1409. So: the loop this issue is about is gone from the stacks, but the surface it lived on cannot currently be exercised on the latest build.

    Suggest closing #1287 as a duplicate of #1325 once someone can confirm idle CPU on a build where the native chat runs.

  9. locked as resolved and limited conversation to collaborators on Sep 26, 2026
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

    P1Urgent regression or broken agent/channel workflow affecting real users now.clawsweeper:needs-infoClawSweeper needs more reporter information before it can verify this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🦐 gold shrimpDecent issue quality, but reproduction details are still incomplete.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions