Every multi-agent architecture makes a bet: that the coordination overhead is cheaper than the context bloat of a monolithic session. Nobody has published the actual cost.
Mohammad Fauzel Sadeghizad ran 45 controlled experiments across 20 programming tasks to measure the fork tax: the performance penalty you pay when you split an agent workflow into subsessions instead of running it inline. The methodology includes pre-registered rubrics, deterministic fixtures, and an independent adversarial verification audit.
The findings are unambiguous. Sometimes the orchestration wins. Sometimes it loses badly. The difference comes down to plumbing, not theory.
The Subsession Invariant
The architectural claim behind subsessions is simple: a coordinator agent spawns child sessions, each child returns a structured report, and the coordinator’s context grows by O(report) instead of O(child transcript).
The human operator sees the entire tree. The coordinator sees only summaries.
This invariant holds mechanically. Every gate, every report contract, every succession letter enforces it. What wasn’t measured was whether the invariant is worth the orchestration cost on real workloads.
Experimental Design
Two arms, identical conditions:
Inline Arm (Role: worker)
A single autonomous session. The subsession toolset is structurally stripped (canSpawn: false). The agent receives the task prompt and executes all code navigation, editing, script execution, and verification directly within its own session.
Orchestrated Arm (Role: coordinator)
A supervisor session authorized to spawn children (canSpawn: true, depthCap: 2). Under pre-registered protocol amendments, the coordinator must delegate work to at least two worker subsessions and synthesize their returned reports before delivering the final answer.
Fairness Controls
- Same model, same temperature, same system prompt structure
- Deterministic fixtures: 20 programming tasks with known correct outputs
- Pre-registered evaluation rubric (RUBRIC.md) before any runs
- Independent adversarial verification audit (results/VERIFICATION.md)
The goal was to isolate orchestration overhead from model variance.
Architecture: How Subsessions Fork
When a coordinator spawns a child session, the runtime performs these steps:
-
Role-typed spawn: Coordinator calls
spawnSubsession(role, brief)with a versioned brief document - Context isolation: Child session starts with the brief, no access to parent transcript
- Append-only journal: Every tool call, every response, every state transition is logged to a checkpoint journal
- Report contract: Child must return a structured report (JSON schema enforced)
- Succession letter: On termination, child writes a succession letter summarizing state for potential successors
- Context merge: Coordinator receives only the report, not the full transcript
The fork tax is the sum of:
- Spawn latency (session initialization, role validation)
- Report serialization overhead
- Coordination token cost (brief + report + synthesis)
- Potential duplication when children re-navigate shared context
Results: When Orchestration Wins and Loses
Metric Inline Arm Orchestrated Arm Delta Mean task completion time 4.2 min 5.8 min +38% Mean token consumption 12,400 18,900 +52% Success rate (correct output) 85% 82% -3% Median context length at completion 8,200 tokens 4,100 tokens (coordinator only) -50% Tasks requiring >3 tool iterations 14/20 16/20 +14%The orchestrated arm consumed 52% more tokens and took 38% longer on average. The success rate dropped slightly.
But the coordinator’s context stayed under 5,000 tokens even on the longest tasks, while the inline agent hit 15,000+ tokens on complex multi-file edits.
Where Orchestration Won
Tasks with clear decomposition boundaries:
- Multi-file refactoring where each file is independent
- Parallel test execution across isolated modules
- Research tasks requiring distinct search strategies
On these tasks, the orchestrated arm was 10-20% faster because children worked in parallel and the coordinator avoided re-reading entire codebases.
Where Orchestration Lost
Tasks requiring tight iteration loops:
- Debugging a single function with multiple test-fix cycles
- Incremental code generation with frequent validation
- Tasks where the “right” decomposition wasn’t obvious upfront
On these tasks, the fork tax was brutal. Spawning a subsession for a 3-line fix cost 2,000+ tokens in brief + report overhead. The inline agent just edited and moved on.
Adversarial Verification Methodology
The independent audit verified:
- Determinism: Re-running the same fixture produced the same output 95% of the time (remaining 5% was model sampling variance)
- Rubric adherence: All runs were scored against the pre-registered rubric, no post-hoc criteria
- No cherry-picking: All 45 runs are published, including failures
- Tool call logs: Full checkpoint journals for every subsession, verifying that coordinators actually delegated
The audit also caught two protocol violations where the coordinator tried to solve tasks inline instead of spawning children. Those runs were excluded and re-run.
Code: Minimal Subsession Spawn
interface SubsessionBrief {
role: "worker" | "researcher" | "reviewer";
task: string;
context: Record<string, unknown>;
constraints: string[];
}
interface SubsessionReport {
status: "success" | "failure" | "blocked";
result: unknown;
tokensUsed: number;
toolCalls: number;
}
async function spawnSubsession(
brief: SubsessionBrief
): Promise<SubsessionReport> {
const session = await runtime.createSession({
role: brief.role,
canSpawn: false, // Workers cannot spawn children
depthCap: 0,
});
await session.initialize(brief);
const result = await session.run();
return {
status: result.status,
result: result.output,
tokensUsed: session.metrics.tokens,
toolCalls: session.metrics.toolCalls,
};
}
// Coordinator pattern
async function coordinatorLoop(task: string) {
const plan = await planDecomposition(task);
const reports = await Promise.all(
plan.subtasks.map(subtask =>
spawnSubsession({
role: "worker",
task: subtask.description,
context: subtask.context,
constraints: subtask.constraints,
})
)
);
return synthesizeReports(reports);
}
Enter fullscreen mode Exit fullscreen mode
The spawn overhead is front-loaded: session creation, role validation, brief serialization. If the child session runs for 30 seconds, that overhead is negligible. If it runs for 5 seconds, the overhead dominates.
Observability: What to Instrument
To measure fork tax in production:
-
Spawn latency histogram: Time from
spawnSubsession()call to first child tool invocation - Report size distribution: Bytes in each report, correlated with task complexity
- Context length at decision points: Coordinator context size when deciding whether to spawn
- Duplication ratio: Tokens spent re-reading shared context across children
- Idle time: Coordinator wall-clock time waiting for child reports
The duplication ratio is the silent killer. If three children each read the same 2,000-token codebase summary, you’ve paid 6,000 tokens for information that could have been read once.
Failure Modes
Premature decomposition
Coordinator spawns children before understanding the task structure. Children thrash, return “blocked” reports, coordinator re-plans. Cost: 3x token budget.
Report contract mismatch
Child returns unstructured text instead of JSON. Coordinator cannot parse, spawns another child to “clean up the report.” Cost: 2x token budget.
Depth limit thrashing
Coordinator hits depthCap, cannot spawn more children, falls back to inline execution. But it already spent tokens on briefs and reports. Cost: orchestration overhead + inline cost.
Parallel duplication
Children independently navigate the same file tree or re-fetch the same API data. No shared cache, no deduplication. Cost: N * fetch overhead.
When to Pay the Fork Tax
Use subsession orchestration when:
- Tasks have clear, stable decomposition boundaries
- Subtasks can run in parallel without shared state
- Coordinator context would exceed 10,000 tokens inline
- You need audit trails for each subtask (checkpoint journals)
- You’re willing to pay 30-50% more tokens for 50% smaller coordinator context
Avoid subsession orchestration when:
- Tasks require tight iteration loops (test-fix-test)
- Decomposition strategy is unclear upfront
- Subtasks are <30 seconds of work (spawn overhead dominates)
- Shared context is large and cannot be cheaply summarized
- You’re optimizing for minimum token cost, not context size
Technical Verdict
The fork tax is real and measurable. On this benchmark, orchestration cost 52% more tokens and took 38% longer. But it kept the coordinator’s context under 5,000 tokens even on complex tasks.
The trade-off is not “orchestration is better” or “inline is better.” The trade-off is: are you willing to pay 50% more tokens to keep your coordinator’s context 50% smaller?
If your bottleneck is context window exhaustion, pay the tax. If your bottleneck is token budget or latency, stay inline.
The measurement methodology matters as much as the results. Pre-registered rubrics, deterministic fixtures, and adversarial verification are the only way to avoid fooling yourself about agent performance.
Run your own benchmark. Publish the logs. Measure the fork tax on your workload before you build the org chart.
Source Links
- Measuring the Multi-Agent Fork Tax (primary source)