Skip to content

[Bug]: headless t3 serve runs at the default V8 heap and dies with "Ineffective mark-compacts near heap limit" after ~3 days with 40+ threads; a server restart drops every running turn #21370

Closed as not planned

Description

@MattRiddell

Before submitting

Area

apps/server

Steps to reproduce

  1. Run t3 serve headlessly with 40+ concurrent threads (Claude Code, Codex, ACP) and a multi-GB state database.
  2. Leave it up for about 3 days.
  3. Watch the process RSS and the V8 heap.

Expected behavior

  • The launcher sets a heap ceiling scaled to the machine (or exposes a documented flag / setting), so a 20-core, 128 GB box does not run the orchestrator at the ~4 GB Node default.
  • The server unloads idle thread state under memory pressure instead of growing until it dies.
  • A crash restart resumes in-flight turns, or at least re-wakes the threads it stopped, so one process crash is not N lost turns.

Actual behavior

Impact

Major degradation or frequent failure

Version or commit

Heap crash: 0.0.43-nightly.20260924.2200. Restart cost: every nightly since, last seen 0.0.46-nightly.20261008.2819. Not re-tested without the heap flag on 2819.

Environment

Linux (Ubuntu, kernel 7.0.0-38-generic), compiled @t3code/t3-linux-x64 binary (Node.js v26.8.2 in crash traces), t3 serve --host 127.0.0.1 --port 3773 --base-dir ~/.t3 as a systemd --user service, headless; Tailscale serve in front; clients: macOS desktop app, iOS app, web. 40–50 live threads at a time over 8 Claude Code instances (claudeAgent), 3 Codex instances and ACP providers (Grok CLI, OpenCode with GLM). ~16,900 threads in statev2.sqlite (40.4 GB). Threads are created, woken and stopped by our own tooling over the /ws RPC (orchestration.dispatchCommand), not by a human in the UI.

Running build: 0.0.46-nightly.20261008.2819 with two local server patches (GitHub PR-sync cadence, Grok multi-task wait). Each draft says whether the patch touches the reported area. 128 GB RAM, 20 cores.

Logs or stack traces

# 2026-09-24 23:57Z (0.0.43-nightly.20260924.2200)
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 ... Mark-Compact 3893.0 (4134.9) -> 3887.1 (4136.4) MB ...
systemd[...]: t3-server.service: Main process exited, code=dumped, status=6/ABRT

# 2026-10-07 (0.0.46-nightly.20261005.2702), see #16794
restart reconciliation ... stoppedSessions: 44

Workaround

A systemd drop-in sets NODE_OPTIONS=--max-old-space-size=12288 for the server process (with a patch so the server removes it from the environment it passes to provider children), plus a timer that alarms when the server's heap climbs. After each restart our tooling re-wakes every thread that had work in flight.

Activity

  1. juliusmarminge commented on Oct 18, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for the detailed numbers. This is the same report as #12584, which is already accepted: headless t3 serve runs at V8's default heap ceiling, aborts with a heap OOM after a day or more of sustained multi-session load, and the restart drops every in-flight provider session. The restart reconciliation side (stoppedSessions) is also tracked in #16794.

    Closing this as a duplicate so the work stays in one place. Please add your figures there (the 3893 MB mark-compact at ~4 GB default, ~14 GB RSS with a 12 GB heap and 40–45 live threads, the 40 GB state DB, and the 0-of-N resume after reboot), since they're a useful second data point for #12584.

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