Built by /blog-post-GM — a Claude Code skill we evolved with our own Evolution engine to write every post in the Godmode voice.
Get free skill (account)
Deep Dive ⏱️ 5 min read

Wave Execution: The Fix That Saved One-Shot Scripts

TL;DR

💥 Problem: Max Agent Teams (3–5 simultaneous agents) was freezing Claude Code terminals to ~1 frame per 5 minutes.
🔍 Diagnosis: Two claude.exe at 1.2GB each, 11 bash shells, zombie process pattern — terminal renderer overwhelmed.
🔧 Fix: Wave execution — same total agents per phase, but launched in waves of max 2 concurrent.
Result: Full stability restored. Same quality, same agent count, zero freezing.
A · WAVE-SCRUB-TIMELINE
SAVED · SCROLL 0%
WAVE 1 · DIAGNOSE A B spawn t=0 WAVE 2 · PATCH C D after wave 1 WAVE 3 · HARDEN E after wave 2 WAVE 4 · SHIP RUN SAVED all clear CPU/RENDERER LOAD 100% 0% W1 W2 W3 SHIP KERNEL-MODE USER-MODE
FOUR WAVES + SHIP · KERNEL CALMS, USER TICKER STAYS ALIVE

🚨 The Symptom

One-Shot Scripts v1.7 introduced Max Agent Teams — 3 to 5 agents launching simultaneously per phase. It was a massive speed upgrade on paper.

Then users started reporting that their terminal was freezing. The Claude Code window would drop to roughly 1 frame every 5 minutes. Completely unusable. But here's the weird part: the rest of the computer was fine.

Key signal: The freeze was isolated to the Claude Code terminal window. Browser, file explorer, everything else worked normally. That ruled out system-wide resource exhaustion immediately.

🕵️ The Investigation

First stop: Task Manager. We needed to see exactly what processes were running and how much they were consuming.

The process snapshot told a clear story of resource overload:

PROCESS SNAPSHOT (during freeze)
================================
claude.exe     1.2 GB RAM    (instance 1)
claude.exe     1.2 GB RAM    (instance 2)
bash.exe       x 11 instances (spawned by agents)

CPU TIME ANALYSIS:
  Kernel mode:  FLAT (no change over 30s)
  User mode:    TICKING (incrementing slowly)
  I/O reads:    ZERO
  I/O writes:   ZERO

Two full Claude instances eating 1.2 GB each. Eleven bash shells spawned by the concurrent agents. That's a lot of processes fighting for the terminal renderer's attention.

🧟 The Zombie That Wasn't Dead

Looking at the CPU time data, the initial call was obvious: this session is dead. Kernel mode was flat, meaning no system calls. No I/O activity at all. Classic zombie process — time to kill it and start over.

But then we spotted something. The user mode time was still ticking. Not fast, but it was incrementing. The session wasn't dead — it was alive, just glacially slow.

🔍 Check Task Manager 📊 Read CPU times ❌ Kernel flat = "dead?" 👀 User mode ticking 🧟 Not dead — zombie! 💡 Renderer bottleneck

The pattern was specific: user mode ticking but kernel mode flat. That meant the Electron process was spending all its time on UI overhead (trying to render agent status streams) but making zero API calls. The backend was alive — the frontend was choking.

Core insight: User mode ticking + kernel mode flat + zero I/O = the process is alive but the terminal renderer is so overwhelmed it can't process anything. It's not a crash — it's a rendering bottleneck.

B · CPU-MODE-SPLIT
CPU TIME · CONCURRENT-AGENT SPAWN
1 bash spawns / 11
Kernel-mode CPU0%
User-mode CPU (renderer ticker)0%
RENDERER QUEUE DRAINED — UI FROZEN @ 1 fps / 5 min

🎯 Root Cause

Claude Code's terminal renderer wasn't built to handle 3–5 concurrent agent status streams updating simultaneously. Each agent produces its own stream of output — tool calls, file reads, code writes, status updates.

Multiply that by 5 agents and the renderer falls over. It's not a memory issue or a CPU issue — it's a rendering throughput issue. The UI simply can't paint that many concurrent status updates fast enough.

📺

The Renderer

Claude Code's terminal uses an Electron-based renderer. It processes agent status streams sequentially — each stream needs screen time to paint its updates.

💥

The Overload

5 agents produce 5 concurrent status streams. The renderer queues up, falls behind, and the UI effectively freezes while the backend keeps chugging along.

🌊 The Fix: Wave Execution

The solution was simple in concept: keep the same total agents per phase, but don't launch them all at once. Instead, launch them in waves of maximum 2 concurrent agents.

A phase that needs 5 agents still gets 5 agents. They just run in waves instead of a stampede:

Phase needs 5 agents (A, B, C, D, E)

🌊 Wave 1: A + B 🌊 Wave 2: C + D 🌊 Wave 3: E

Same 5 agents. Same quality. Max 2 running at any moment.

The instruction added to every phase script was explicit:

WAVE LIMIT: Max 2 agents concurrent per wave.
Do NOT reduce total agent count.

Example for 5 agents:
  Wave 1: Agent A + Agent B (run simultaneously)
  Wave 2: Agent C + Agent D (run simultaneously)
  Wave 3: Agent E (runs alone)

Total agents: still 5. Concurrency: max 2.

🤯 The Misinterpretation

Here's where it gets interesting. The first version of the fix said "wave limit: max 2 concurrent." Seemed clear enough. But the model read it as "max 2 agents total per phase."

Instead of launching 5 agents in waves of 2, it was only launching 2 agents total. That's a massive quality regression — you've cut your research and testing capacity by more than half.

❌ Fix v1 (Misread)

  • "Max 2 concurrent"
  • Model interpreted: 2 agents total
  • Phase got 2 agents instead of 5
  • Quality dropped significantly

✅ Fix v2 (Explicit)

  • Spelled out wave pattern with example
  • "Do NOT reduce total agent count"
  • Wave 1: A+B, Wave 2: C+D, Wave 3: E
  • Quality preserved, stability fixed

Lesson learned: When writing instructions for an AI model, ambiguity kills. "Max 2 concurrent" is technically correct but easily misread. An explicit wave-by-wave example with a bold "Do NOT reduce total" leaves zero room for misinterpretation.

D · INTERPRETATION-FORK
SAME PHRASE · TWO READINGS · ONE SHIPS SCROLL 0%
v1 misread — "max 2 total"
model interpreted: cap concurrency by reducing count
A
B
C
D
E
·
·
·
·
·
spawned 0 / 5
quality
outcome
phase
v2 explicit — "max 2 concurrent, total preserved"
spelled out wave pattern + "do NOT reduce total"
A
B
C
D
E
·
·
·
·
·
spawned 0 / 5
quality
outcome
phase
v1: cap by cutting · v2: cap by waving

📊 Before and After

Metric Before (v1.7) After (Wave Execution)
Agents per phase 3–5 3–5 (unchanged)
Max concurrent 3–5 (all at once) 2 (waves)
Terminal stability Freezes to ~1 fps/5min Smooth, no freezing
Output quality High (when it finished) High (identical)
Completion rate Unreliable — often killed Runs to completion
RAM usage 2.4 GB+ (2 instances) Stable, single instance
Bash processes 11+ simultaneous Controlled, wave-limited
0
Terminal Freezes
100%
Agent Capacity
2
Max Concurrent

🚗 The Real-World Analogy

Think of a highway on-ramp during rush hour. Without metering, 50 cars try to merge onto the highway at the same time. The highway grinds to a halt — nobody moves, everyone's stuck.

Install a ramp meter that lets 2 cars through every few seconds and something magical happens: the same number of cars get through, they just don't all try to merge at once. Traffic flows. No gridlock. Same throughput, dramatically better flow.

🛑

No Metering (v1.7)

All 5 agents merge at once. The terminal "highway" locks up. Everyone waits. Some never finish. The session gets killed out of frustration.

🚦

Ramp Metering (Waves)

2 agents merge at a time. Terminal stays smooth. All 5 agents complete their work. Same destination, no gridlock getting there.

Wave execution is ramp metering for AI agents. The throughput is identical — you're just preventing the bottleneck that kills everything.

C · RAMP-METER-ANALOGY
METER STATE: ALL-GREEN (no metering) FREEWAY: 75 mph
FREEWAY ONRAMP FLOW →

Try One-Shot Scripts with Wave Execution

Same parallel agent power, zero terminal crashes. Ultrathink + Agent Teams + Wave Execution — all built in.

Get Access Learn More