Skip to content

feat(desktop): reduce EDR/security agent CPU usage from idle terminals and active agent sessions #3235

Closed as duplicate

Description

@felixbarny

Background

Users on machines with kernel-level EDR agents (e.g. Elastic Endpoint) experience sustained high CPU usage (>100–200%) from the security agent even when Superset is completely idle. EDR agents intercept and inspect every file open, stat, and process spawn system-wide, so Superset's background activity directly drives the EDR's CPU load.

Root causes identified

Two independent sources were found via fs_usage and sample profiling on macOS:

1. Scrollback file — continuous writes on every PTY event

HistoryWriter.write() calls stream.write() on every PTY data chunk. With active Claude Code agent sessions producing dense terminal output, this causes scrollback.bin to be modified hundreds of times per second per session. Each mtime update causes the EDR to re-stat and re-open the file for inspection.

2. Port scanner — ps + lsof spawned every 2.5s per session

PortManager runs a periodic scan every 2,500ms that calls pidtree (spawning ps) for each registered terminal session, then runs lsof across all discovered PIDs. With 13 open sessions this produces ~14 process spawns every 2.5 seconds. EDR agents intercept every process spawn and monitor the files those processes open — lsof in particular opens thousands of file descriptors per invocation as it enumerates all sockets system-wide.

Proposed fixes

  1. Scrollback write debounce (terminal-history.ts): Buffer PTY output in memory and flush to disk at most once every 250ms. Reduces file modification events by batching many small PTY chunks into a single write. No impact on terminal responsiveness — the in-memory buffer is the source of truth; disk writes are just for cold restore.

  2. Port scan interval (port-manager.ts): Increase from 2,500ms → 10,000ms. The hint-based scan (fires within 500ms of seeing "listening on port X" in output) handles prompt detection; the periodic scan is just a safety-net sweep.

  3. Skip idle sessions in periodic scan (port-manager.ts): Skip any session that has no currently-detected ports and has not seen port-hint output in the last 60 seconds. A machine with 13 idle terminal sessions running no dev servers produces zero ps/lsof spawns per cycle. Hint scans still fire immediately when a dev server starts.

Result

With all three fixes applied, Elastic Endpoint CPU drops from >200% (sustained, with agents running) and ~120% (idle terminals) to under 20% most of the time with 13 open sessions. Occasional spikes to ~60% appear to be within Elastic Endpoint's normal operating range independent of Superset. Baseline CPU without Superset open is <2%, so some overhead remains, but it is well within a tolerable range.

Not addressed

Claude Code agent sessions (each instance continuously stats .claude.json, .git/HEAD, skills, and commands). This is Claude Code's own behavior and outside Superset's control, but it contributes significantly when multiple agents are running.

Activity

  1. added 2 commits that reference this issue on Apr 7, 2026
    a3f8560
    a4431b2
  2. added a commit that references this issue on Apr 7, 2026
  3. added a commit that references this issue on Apr 7, 2026
    a46c6bd
  4. felixbarny commented on Apr 7, 2026

    @felixbarny
    Author

    Three independent PRs implementing the proposed fixes:

  5. felixbarny commented on Apr 7, 2026

    @felixbarny
    Author

    PRs #3237, #3238, and #3239 have been closed in favour of #3236, which was opened by the triage agent and covers all three fixes in a single PR. #3236 is a better implementation overall:

    • Uses an array-based debounce buffer (avoids intermediate string concatenation)
    • Fixes a pre-existing flush() hang bug we missed: the original code always registered a drain listener, but if stream.write() never returned false, drain never fires and flush() would hang indefinitely
    • Cleaner hint-activity tracking via a separate lastHintActivity map rather than embedding the timestamp in the session interfaces
    • Properly cleans up hint state in unregisterDaemonSession (we overlooked this)
    • Exports constants for testability and includes tests

    A review comment has been left on #3236 suggesting one additional guard: short-circuiting scanAllSessions() when no sessions are registered at all.

  6. felixbarny commented on Apr 20, 2026

    @felixbarny
    Author

    @saddlepaddle thanks a lot for handling #3372. However, with the latest update, I still get a very high CPU usage for my endpoint agent. Could you have another look at this issue specifically, especially the scrollback file debounce? Thanks!

  7. felixbarny commented on May 7, 2026

    @felixbarny
    Author

    @saddlepaddle @Kitenite this is still an issue even with v2 enabled. The CPU usage of the endpoint agent goes through the roof when opening superset. Due to this, I currently need to run superset form a local build. Could you have a look, please? Any way I could help out here?

  8. nate-credoai commented on May 11, 2026

    @nate-credoai

    I'm having the same issue and it's a blocker for me to continue using this which is a bummer.

  9. mvoehringer commented on May 21, 2026

    @mvoehringer

    I’m seeing this same issue on both v1 and v2, though v2 seems even worse. I use an MDM-managed MacBook Pro M1 with around 20 open workspaces. Whenever Superset is open, my background virus scanner hits 100% CPU usage.

    This makes the app completely unusable.

    Version 1.10.2

  10. Kitenite commented on Jul 11, 2026

    @Kitenite
    Member

    Closing as a duplicate of #5602, the consolidated tracker for stale performance issues from the July 2026 stale-issue sweep (no activity since 2026-06-01). If this still applies on a current build, comment on #5602 and we'll reopen.

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