# Mastering AI Efficiency: Orchestrating 100+ Claude Code Agents in Headless Mode

> enable unparalleled productivity by coordinating a swarm of AI coding agents in headless mode for smooth parallel task execution.
> By Dave · 2026-07-14
> Source: https://otf-kit.dev/blog/ai-agent-orchestration

100+ coding agents, one orchestrator, zero babysitting — that is what Claude Code's headless mode enables. The pattern is genuinely well-suited to how modern software wants to be built: define the work, hand it to a fleet, read the results when the fleet reports. For teams already drowning in PR queues, this is the rare technique that scales linearly with the number of agents rather than your calendar.

That said, the pattern is not magic. Run 100 agents with no plan and you get 100 stacks of half-finished work. The source on this — [Orchestrating 100+ AI Agents with Claude Code Headless Mode](https://techgig.com/news/ai/orchestrating-100-ai-agents-with-claude-code-headless-mode/132382034) — calls out three strategies that decide which side of that line you land on. Let's walk through what headless orchestration is, how the CLI surfaces it, and the part that stays constant when the model underneath changes.

## What headless orchestration actually is

Headless orchestration is the practice of running coding agents — Claude Code, Codex, and peers — without a human in the loop on every turn. You give each agent a task; it works autonomously; it reports a result. Above them sits an orchestrator agent whose job is coordination, not coding: it plans, delegates, aggregates results, and verifies.

The mental model is "software project, but every contributor is a model running in its own shell." The orchestrator is the engineering manager. The workers are the engineers. Each worker has a sandbox, a task, and a deadline.

Headless mode is the CLI surface that makes this tractable — a non-interactive invocation where agents start, run, finish, and exit without an attached terminal. Same idea as a headless browser: no chrome, no chat pane, just a process you can fork.

## How the headless CLI works

In an interactive IDE session, every turn is a back-and-forth with a human attached. Headless mode is the one-shot sibling:

```bash
# Pseudocode representing the headless pattern.
# (See the official Claude Code docs for the current flag set.)
claude-code headless \
  --task "refactor src/billing/* to remove the legacy adapter" \
  --workspace ./worktrees/agent-42 \
  --report-to ./reports/agent-42.json
```

That command boots an agent in its own context, scopes it to a workspace, and tells it where to write its report. No TTY. No streaming chat. The session is a process like any other — and that is exactly what makes orchestration tractable, because a process can be forked, awaited, and aggregated by a parent.

The orchestrator then runs a loop like this:

```ts
// Each call spawns its own headless agent session.
async function orchestrate(tasks: Task[]) {
  const results = await Promise.allSettled(tasks.map(runHeadless))

  // First strategy: each agent self-verifies, then the orchestrator triages.
  return results
    .filter((r) => r.status === 'fulfilled' && selfVerify(r.value))
    .map((r) => (r as PromiseFulfilledResult<Result>).value)
}
```

Two design choices matter here. First, `Promise.allSettled`, not `Promise.all` — one failed agent should not nuke the whole batch. Second, `selfVerify` — that is strategy number one.

## The three rules the source calls out

Strip the article down and there are three rules that decide whether the pattern holds up:

1. **Agents must verify their own work.** With 100 agents running, you cannot be the reviewer for all 100 PRs. Each agent needs an in-loop self-check: run the tests, diff against the spec, fail loudly if any check fails. The orchestrator's job is then to triage — accept, retry, escalate — not to debug.
2. **Tasks must be suited to autonomous execution.** Refactoring is the canonical example: the input is existing code, the output is existing code that does the same thing in a less-bad way, and a test suite is the most natural spec. Work that requires human judgment ("is this design the right design?") is the wrong shape for the pattern.
3. **Agents must have all the tools and permissions they need.** A headless agent that hits a permission prompt blocks until a human clicks Approve. That defeats the point. Pre-grant the scopes, scope them tightly to the task, and let the agent run.

Run those three and your 100 agents tend to look like 100 PRs. Skip any one and the same 100 tend to look like 100 stuck terminals waiting for input that will never come.

## A minimal orchestrator you can run today

A workable setup has four pieces: a task queue, a worker pool, a verify step, and an aggregator. Here is a skeletal version you can actually type:

```ts
import { readFile, writeFile } from 'node:fs/promises'
import { spawn } from 'node:child_process'

type Task = {
  id: string
  prompt: string
  workspace: string
  reportPath: string
}

// 1. The queue — could be a DB, could be a JSON file.
async function loadTasks(): Promise<Task[]> {
  return JSON.parse(await readFile('./queue.json', 'utf8'))
}

// 2. The worker — spawn one headless session per task.
async function runWorker(task: Task): Promise<void> {
  return new Promise((resolve, reject) => {
    const child = spawn('claude-code', [
      'headless',
      '--task', task.prompt,
      '--workspace', task.workspace,
      '--report-to', task.reportPath,
    ], { stdio: 'inherit' })

    child.on('exit', (code) => {
      code === 0
        ? resolve()
        : reject(new Error(`agent ${task.id} exited ${code}`))
    })
  })
}

// 3 + 4. The orchestrator — fan out, gather, summarize.
async function orchestrate(parallel = 16) {
  const tasks = await loadTasks()

  // Simple bounded pool: at most `parallel` agents in flight.
  const results: PromiseSettledResult<void>[] = []
  for (let i = 0; i < tasks.length; i += parallel) {
    const batch = tasks.slice(i, i + parallel)
    const settled = await Promise.allSettled(batch.map(runWorker))
    results.push(...settled)
  }

  const ok = results.filter((r) => r.status === 'fulfilled').length
  await writeFile('./summary.json', JSON.stringify(results, null, 2))
  console.log(`${ok}/${tasks.length} agents finished cleanly`)
}
```

That is a complete orchestrator: read a queue, fan out across N parallel workers, capture each agent's exit code, write a summary, and let the orchestrator agent itself stay focused on planning the next batch. Swap `claude-code` for `codex` and the same script drives a different fleet — the shape of the orchestration does not depend on which model is inside.

The 100-agent headline is a marketing number; the actual figure that matters is the one your hardware, your rate limits, and your CI runners can sustain. Start at N=4, watch the queue, scale up.

## The part that doesn't change when the model does

Here is the part the launch announcements skip: orchestration patterns survive model releases; the cross-platform UI contract your agents build against does not. If you are pointing 100 agents at a web + iOS + Android codebase, every one of them needs to produce a component that renders the same way on all three surfaces. That is the durable layer underneath the agent churn.

The shape of that durable layer:

- One component API, one set of props, three render targets.
- A single design-token source so the agents cannot drift on spacing or color.
- A documented component contract — what slots, what states, what variants — that an agent can read once and apply consistently.
- Validation at the boundary: every PR has to pass the same cross-platform visual regression suite, regardless of which of the 100 agents produced it.

When the model under your orchestrator changes — and it will, every quarter — those 100 agents can be retrained overnight against the new weights. The component contract they target stays. The PRs keep landing in the same shape.

That is the only piece of the stack worth treating as infrastructure: the contract between the agent fleet and the surface the agents are building. Everything above it (the model, the orchestrator framework, the CLI flags) churns. Everything below it (the runtime, the bundler, the platform shims) is already abstracted. The contract in the middle is where 100-agent orchestration is won or lost.

## What this gets you

Refactoring is the proof point. A 200k-line monorepo with 2,000 files of legacy adapters does not get cleaned up by a single agent in a single session. It does get cleaned up by 50 agents, each owning a subtree, each verifying against the same test suite, each reporting a diff to the orchestrator. The orchestrator merges, a human reviews the merged output, and the original engineer who dreaded the work is free to do something harder.

That is the honest pitch for headless orchestration right now. Not "replace the engineer," but "parallelize the work that did not need the engineer in the first place." The orchestrator pattern, the headless CLI, and the three discipline rules are the difference between a fleet that ships and a fleet that hangs.