What variant of Codex are you using?
Codex App primarily. The orchestration primitive would ideally be shared with CLI/tool-backed Codex surfaces.
What feature would you like to see?
Summary
Codex now has most of the pieces needed for heterogeneous multi-agent work: subagents, per-agent model configuration, async orchestration, and configurable concurrency.
The missing primitive is bounded batch fan-out.
A coordinator should be able to submit a large set of independent tasks in one operation, have Codex schedule them across cheaper/faster worker agents with explicit limits, then collect bounded results for synthesis.
The motivating shape is:
strong coordinator
|
decompose / schedule
|
+-------------+-------------+
| | |
fast worker fast worker fast worker
| | |
+-------------+-------------+
|
coordinator
reduce
For example: a Sol coordinator analyzing a large multi-repository system could dispatch 80 independent repository audits to Spark workers, run at most 32 concurrently, then synthesize their findings.
This should not require the coordinator to make 80 individual spawn_agent calls and manually manage 80 wait_agent lifecycles.
Problem
spawn_agent is a good primitive for small, adaptive teams where the parent decides what to delegate one task at a time.
It is a poor primitive for workloads where the complete work set is already known:
- inspect every package in a monorepo;
- review 100 independent files/modules;
- run the same migration audit across many services;
- investigate one question independently against many repositories;
- generate bounded implementation/review tasks from an already-computed plan.
In these cases, repeated parent-side spawn/wait decisions add orchestration turns and context churn without adding useful reasoning.
Simply increasing agents.max_threads does not solve that. Batch size and concurrency are different things.
I may want to submit 200 tasks while allowing only 16 or 32 workers to execute concurrently.
Proposed shape
The exact API is not important, but conceptually something like:
batch = spawn_batch(
worker_profile = "fast_worker",
tasks = [...],
concurrency = 32,
max_tokens_per_worker = 20000,
total_budget = ...,
max_result_size = ...,
recursive_spawn = false,
)
results = wait_batch(batch)
tasks could contain independent prompts plus optional scoped context/path information.
spawn_batch should create one schedulable batch, not require the model to emit N individual spawn calls.
Important semantics
Batch size != concurrency
A batch may contain 200 tasks while the scheduler runs only 16 concurrently.
Excess work should queue rather than requiring the parent model to manage free slots.
Heterogeneous workers
The worker model/profile should be selectable independently from the coordinator.
A common configuration would be:
coordinator: expensive/high-reasoning model
workers: fast/cheap model
reviewer: optional stronger model
This is where models such as Spark are particularly useful: not necessarily as the coordinator, but as high-throughput bounded workers.
Explicit budgets
Large fan-out needs guardrails, not just a higher thread limit.
Useful controls would include:
- maximum batch size;
- maximum active workers;
- model/profile allowlist;
- per-worker token or credit budget;
- aggregate batch budget;
- timeout;
- sandbox/tool permissions;
- maximum result size;
- maximum subagent depth;
- queue vs fail behavior when capacity is exhausted.
A parent should be able to say “up to 32 Spark workers, 20k tokens each, read-only, depth 1” rather than implicitly creating an uncontrolled swarm.
Bounded result aggregation
The coordinator usually does not need the complete transcript of every worker.
By default, batch completion should return something closer to:
task id
status
final worker result
usage
optional artifact references
rather than injecting every worker's full interaction history into the parent context.
This matters once fan-out becomes large.
Partial failure
wait_batch should preserve successful results when some tasks fail, time out, or are cancelled.
It should be possible to retry selected task IDs without rerunning the whole batch.
Cancellation and observability
A batch should have an ID and expose:
queued
running
succeeded
failed
cancelled
token/credit usage
The user should be able to cancel the batch or individual tasks.
Why make this a first-class primitive?
A sufficiently capable coordinator can approximate this today with repeated spawn_agent calls.
But that pushes deterministic scheduler work back into model reasoning:
find free slot
spawn worker
remember worker id
wait
inspect completion
spawn next
repeat
None of those steps requires a frontier reasoning model.
A runtime-level batch primitive could handle queueing, limits, cancellation and result collection deterministically while leaving the coordinator responsible for the parts that actually require reasoning:
decomposition
task specification
dependency identification
final synthesis
This also makes very large fan-out safer. The runtime can enforce hard budgets even if the coordinator attempts to over-spawn.
Concrete example
Consider an architecture audit over 80 repositories.
The coordinator first determines that each repository can be inspected independently.
Desired execution:
Sol:
build 80 bounded audit tasks
|
v
spawn_batch:
worker = Spark
tasks = 80
concurrency = 24
read-only
depth = 1
|
v
scheduler:
24 running
56 queued
|
v
80 bounded reports
|
v
Sol:
cross-repo synthesis
contradictions
architecture decision
The expensive coordinator is used where its reasoning matters. The fast workers provide breadth.
Acceptance criteria
- A coordinator can submit N independent subagent tasks in one tool/runtime operation.
- Batch size may exceed active concurrency.
- Queued work starts automatically as worker capacity becomes available.
- Worker model/profile may differ from the coordinator.
- Per-worker and aggregate budgets are enforceable by the runtime.
- Worker recursion/depth can be disabled or bounded.
- Batch status, usage, cancellation and partial failures are observable.
- Results can be collected without importing full worker transcripts into parent context by default.
- Individual failed tasks can be retried without rerunning successful tasks.
- Existing
spawn_agent remains available for adaptive one-off delegation.
This is intended to complement, not replace, normal subagents and agent teams.
Additional information
Related requests
I searched the existing Codex issues before filing this.
Two current reports also show why explicit runtime scheduling and budgets matter:
I am not asking for an unlimited subagent count.
I am asking for a bounded map/fan-out primitive where the runtime, rather than the coordinator model, handles queueing, concurrency, budgets and result collection.
What variant of Codex are you using?
Codex App primarily. The orchestration primitive would ideally be shared with CLI/tool-backed Codex surfaces.
What feature would you like to see?
Summary
Codex now has most of the pieces needed for heterogeneous multi-agent work: subagents, per-agent model configuration, async orchestration, and configurable concurrency.
The missing primitive is bounded batch fan-out.
A coordinator should be able to submit a large set of independent tasks in one operation, have Codex schedule them across cheaper/faster worker agents with explicit limits, then collect bounded results for synthesis.
The motivating shape is:
For example: a Sol coordinator analyzing a large multi-repository system could dispatch 80 independent repository audits to Spark workers, run at most 32 concurrently, then synthesize their findings.
This should not require the coordinator to make 80 individual
spawn_agentcalls and manually manage 80wait_agentlifecycles.Problem
spawn_agentis a good primitive for small, adaptive teams where the parent decides what to delegate one task at a time.It is a poor primitive for workloads where the complete work set is already known:
In these cases, repeated parent-side spawn/wait decisions add orchestration turns and context churn without adding useful reasoning.
Simply increasing
agents.max_threadsdoes not solve that. Batch size and concurrency are different things.I may want to submit 200 tasks while allowing only 16 or 32 workers to execute concurrently.
Proposed shape
The exact API is not important, but conceptually something like:
taskscould contain independent prompts plus optional scoped context/path information.spawn_batchshould create one schedulable batch, not require the model to emit N individual spawn calls.Important semantics
Batch size != concurrency
A batch may contain 200 tasks while the scheduler runs only 16 concurrently.
Excess work should queue rather than requiring the parent model to manage free slots.
Heterogeneous workers
The worker model/profile should be selectable independently from the coordinator.
A common configuration would be:
This is where models such as Spark are particularly useful: not necessarily as the coordinator, but as high-throughput bounded workers.
Explicit budgets
Large fan-out needs guardrails, not just a higher thread limit.
Useful controls would include:
A parent should be able to say “up to 32 Spark workers, 20k tokens each, read-only, depth 1” rather than implicitly creating an uncontrolled swarm.
Bounded result aggregation
The coordinator usually does not need the complete transcript of every worker.
By default, batch completion should return something closer to:
rather than injecting every worker's full interaction history into the parent context.
This matters once fan-out becomes large.
Partial failure
wait_batchshould preserve successful results when some tasks fail, time out, or are cancelled.It should be possible to retry selected task IDs without rerunning the whole batch.
Cancellation and observability
A batch should have an ID and expose:
The user should be able to cancel the batch or individual tasks.
Why make this a first-class primitive?
A sufficiently capable coordinator can approximate this today with repeated
spawn_agentcalls.But that pushes deterministic scheduler work back into model reasoning:
None of those steps requires a frontier reasoning model.
A runtime-level batch primitive could handle queueing, limits, cancellation and result collection deterministically while leaving the coordinator responsible for the parts that actually require reasoning:
This also makes very large fan-out safer. The runtime can enforce hard budgets even if the coordinator attempts to over-spawn.
Concrete example
Consider an architecture audit over 80 repositories.
The coordinator first determines that each repository can be inspected independently.
Desired execution:
The expensive coordinator is used where its reasoning matters. The fast workers provide breadth.
Acceptance criteria
spawn_agentremains available for adaptive one-off delegation.This is intended to complement, not replace, normal subagents and agent teams.
Additional information
Related requests
I searched the existing Codex issues before filing this.
Two current reports also show why explicit runtime scheduling and budgets matter:
ultraeffort spawns multi-agent swarms despitefeatures.multi_agent=false, consuming 250–600 credits per read-only task without batching guidance #35177 — uncontrolled Sol swarms can consume very large amounts of usage.I am not asking for an unlimited subagent count.
I am asking for a bounded map/fan-out primitive where the runtime, rather than the coordinator model, handles queueing, concurrency, budgets and result collection.