[BUG] Desktop app artifact-preview renderer balloons to 7.6 GB, driving the macOS memory pressure that makes the Claude Code daemon evict background sessions

Open 💬 3 comments Opened Jul 3, 2026 by vguerci

Environment

  • Claude desktop app: 1.18286.0 (macOS)
  • Claude Code CLI: 2.1.199
  • OS: macOS 26.5.1 (25F80), arm64, 16 GB RAM
  • Heavy claude agents user: ~10–15 concurrent background sessions, ~70 local sessions total on disk

Summary

Two Anthropic products form a self-inflicted feedback loop on the same machine:

  1. A desktop-app renderer ballooned to a 7.65 GB real footprint (mostly compressed by macOS, so it's invisible in ps RSS — only top -o mem / footprint show it). Timeline evidence points at the claude.ai/code artifact HTML-preview window: the renderer spawned within a minute of [Preview] Created Claude page preview for an artifact (a static HTML page of inline SVGs), then sat open ~4.7 h with the app's periodic capturePreviewScreenshotIfChanged running against it.
  2. That pushes kern.memorystatus_vm_pressure_level to 2 (warn).
  3. The Claude Code daemon (claude daemon) treats that as low memory (evictions correlate with pressure level ≥ 2 regardless of free bytes — see Evidence) and retires settled bg workers on every new spawn.
  4. Net effect: background sessions "randomly disconnect" 40–75× per day. The daemon log shows 225 eviction events over 4 days, firing with 58–250 MB free.
  5. This also breaks mobile Remote Control: an evicted session drops off the roster and does not restart, so from the phone it just goes unreachable — the mobile app offers no way to revive it; the only workaround is a shell on the host (e.g. ssh) to resume it via claude agents.

The daemon's eviction behavior is reasonable in isolation; the desktop app being the dominant source of the pressure is the bug. Users experience it as "my bg sessions keep dying," with no visible culprit because the renderer's RSS looks tiny.

Evidence

Renderer footprint (window sat idle, untouched for hours):

$ top -l 1 -o mem -stats pid,mem,command
PID    MEM   COMMAND
80601  7655M Claude Helper (R   ← desktop app renderer, ~4h40 old

ps RSS for the same process read ~0–331 MB — macOS had compressed the heap (system compressor held ~28 GB of data in 7.2 GB at the time).

Renderer identity — the artifact preview window (~/Library/Logs/Claude/main.log): the ballooned renderer spawned at ~09:35 (from its etime); the only window creation in that interval is:

2026-07-03 09:34:31 [info] [Preview] Created Claude page context { serverId: 'html-preview-…', totalContexts: 1 }
2026-07-03 09:34:31 [info] [Preview] Created Claude page preview { serverId: 'html-preview-…' }
2026-07-03 09:34:31 [warn] [Preview] capturePreviewScreenshotIfChanged failed: {

The previewed artifact was a self-contained static HTML page (an icon-comparison grid of inline SVGs) — nothing that should grow, yet the renderer reached 7.65 GB and no [Preview] destroy event ever fired. For contrast, the app's main renderer (session sidebar, same uptime) stayed at ~660 MB.

Daemon evictions driven by that pressure (~/.claude/daemon.log):

[2026-07-03T11:58:21] [bg] bg: low memory (92MB free) — retiring settled workers before spawning 6cf7960f
[2026-07-03T12:01:53] [bg] bg: low memory (131MB free) — retiring settled workers before spawning 851b7308

225 occurrences over 4 days (75 on 06-30, 49 on 07-01, 61 on 07-02, 40 on 07-03).

Causality confirmed: killing renderer PID 80601 dropped kern.memorystatus_vm_pressure_level from 2 → 1 within seconds, and the evictions stopped.

The trigger tracks the macOS pressure level, not free bytes: evictions fired at free-RAM values anywhere from 58 MB to 1.3 GB (median ~150 MB), but correlate exactly with kern.memorystatus_vm_pressure_level >= 2 — including the instant recovery when the renderer died. This matches the memory-pressure reaping behavior described in the 2.1.193 release notes and #73440.

Expected behavior

  • An artifact preview of a static HTML page should not grow without bound; the preview renderer should be bounded, and an idle preview window should be unloaded or its capture loop stopped.
  • Ideally the daemon's low-memory threshold would be user-tunable and documented (like CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP is for background shells) — but fixing the renderer leak removes the trigger.

Related issues (searched — none report this loop)

  • #73440 — same memory-pressure trigger family, different victim: the memory-pressure reaping of background shell commands added in 2.1.193 (per the release notes) killing active run_in_background tasks.
  • #72719 — bg workers crash-loop under memory pressure, misreported as "exit 1 before init".
  • #62048 — desktop app OOM on 8 GB M2 from the hardcoded 4 GB VM; a different desktop memory mechanism (the always-warm Cowork VM also contributes ~1.1 GB here).
  • #73631 — daemon-side accumulation of stale "done" sessions.

None identify a desktop renderer as the pressure source, nor the RSS-vs-compressed-footprint blindspot that hides it.

Steps to reproduce

  1. On a 16 GB Mac, keep ~10 concurrent background sessions running (visible in claude agents).
  2. In the Claude desktop app, open a claude.ai/code artifact HTML preview and leave that window open for several hours.
  3. Watch top -o mem: the preview renderer's footprint climbs into the GBs while ps RSS stays small.
  4. Watch ~/.claude/daemon.log: every bg spawn logs bg: low memory — retiring settled workers, and previously-settled bg sessions drop off claude agents.

---

Edit: the initial version attributed the balloon to the main window mirroring local sessions; log-timeline analysis shows the ballooned renderer was the artifact HTML-preview window (the main renderer stayed at ~660 MB). Body corrected accordingly.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗