// Orchestration · ~12 min
Parallel Fan-Out / Fan-In
Reach for it when: When independent sub-tasks can run at once and merge into one answer.
// 60-second mental model
How to hold it in your head
Split independent work. Run it at the same time. Merge when every branch returns — or when your join rule says “enough.”
Fan-out/fan-in dispatches independent sub-tasks concurrently, then joins results with an explicit merge policy (wait-all, wait-k, or first-success).
// Mini architecture
Fan-out independent work · join with a rule
┌────────────┐
│ Dispatcher │
└─────┬──────┘
┌───────────┼───────────┐
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│ Branch │ │ Branch │ │ Branch │
│ A │ │ B │ │ C │
└───┬────┘ └───┬────┘ └───┬────┘
└───────────┼───────────┘
▼
┌────────────┐
│ Join/merge │ → Final
└────────────┘Branches must be independent. If B needs A’s output, you wanted a pipeline — not fan-out.
// Mini-project
Three-source brief, wait-all join (stub)
Dispatcher + three stub branches
Goal: Fan out research stubs for docs, blog, and changelog; merge only after all three return.
- Dispatcher receives a product question.
- Fan out `branch_docs`, `branch_blog`, `branch_changelog` stubs in parallel (Promise.all).
- Join rule: wait-all; on any failure, mark that branch `null` and continue.
- Merger builds a brief with one section per non-null branch.
- Refuse a serial “call A then B then C” path in the stub runner.
- Log wall-clock vs. sum-of-branch times to show the point.
Simulated delays are fine. The lesson is independence + join policy, not real crawlers.
// Common failure
What goes wrong
Symptom
Fake parallelism — branches secretly depend on each other and deadlock or race.
Fix
Assert independence in the dispatcher. Dependent work belongs in a sequential pipeline.
// Self-reflection
Sit with this
Which of your “parallel” agent runs still waits on a hidden shared file?
Session only. Nothing is saved.