[BUG] Interactive input latency degrades to unusable well before the 1000-agent workflow cap
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Summary
Workflow enforces a hard cap of 1000 agents per run ("a runaway-loop backstop set far
above any real workflow"). In practice the interactive TUI becomes unusable long before that
ceiling. In a single long-running workflow that reached 744 agents, per-keystroke input
latency in the main terminal degraded progressively over a full day, to the point where typing
was impractical.
The two limits are inconsistent: the guardrail that stops you sits at 1000, but the thing that
actually breaks is the interface, at roughly 70% of that. Either the cap should reflect what
the renderer can sustain, or the renderer should sustain the cap.
Observed: input latency grows roughly in step with cumulative agent count. At ~744 agents the
session was effectively untypeable. Restarting the session restores responsiveness immediately.
Workaround (for anyone hitting this)
Don't accumulate agents in one run. If your orchestration has a natural work-item boundary, drive
one top-level workflow run per item from an external supervisor rather than nesting child
workflows inside a single long-lived parent. Each run then gets a fresh progress tree, a fresh
agent budget, and releases memory on exit. Nested workflow() calls specifically do not give
you this — they share the parent's counter and tree by design.
What Should Happen?
Expected: interactive responsiveness should be independent of how many agents a background
workflow has spawned, or at minimum should hold up to the documented 1000-agent cap.
Suggested fixes (either would resolve it)
- Virtualize the progress tree. Render only the visible viewport and make the /workflow view fast, it lags seconds while scrolling from one to the next as if the whole transcript is included when switching. Completed agents are the
overwhelming majority of rows in a long run and carry almost no live information.
- Lower the agent cap to a value the renderer demonstrably sustains, and say so in the
Workflow tool docs. Less desirable — it removes capability rather than fixing the defect —
but it would at least make the two limits consistent.
Error Messages/Logs
Steps to Reproduce
- Author a workflow that fans out over many items and spawns agents across a long sequence of
phases. In my case a self-draining milestone loop invoked a child workflow per work item via
nested workflow({scriptPath}); nested workflows share the parent run's agent counter and
progress tree, so the count accumulates monotonically across the whole run.
- Let it run for several hours in an interactive session.
- Type in the main terminal periodically as the agent count climbs.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.220
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
IntelliJ IDEA terminal
Additional Information
Measured on the affected machine while the workflow was live:
| Signal | Value |
|---|---|
| Agent transcripts in the single run dir | 744 (87 MB) |
| Agent rows actually displayed in terminal | ~360 |
| Peak CPU of any claude process (8s sample) | 18% of one core |
| Peak RSS of the session process | 594 MB |
| Logical cores available | 32 |
No process was CPU-bound, memory was unremarkable, and the machine had ample headroom. Latency
nonetheless tracked agent count. That pattern points at per-input re-render of the progress tree
rather than any resource ceiling.
Confidence note: the mechanism (full re-render/repaint of the agent list per keystroke
rather than a virtualized or diffed update) is an inference from external symptoms. I did not
inspect the renderer — the distribution is a ~265 MB single-executable blob with the bundle
minified — so I cannot confirm the code path. The symptom-to-resource mismatch above is what I
can actually attest to. The fact that ~360 of 744 rows were displayed suggests some bounding
already exists but is insufficient, though I could not separate that from terminal scrollback
truncation.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗