Advanced11 min
Deferred Nodes
Most parallel-graph bugs happen at the reduce step: the node fires after the first branch completes, not all of them. defer=True on add_node() turns any node into a synchronization barrier — it stays queued until every pending task in the run has finished, so it always sees the complete accumulated state.
Quick Reference
- →defer=True: passed to add_node() — there is no @defer decorator and no 'defer' export from langgraph.graph
- →Semantics: 'will not execute until all pending tasks are finished' — a run-level guarantee, not an edge-level one
- →Map-reduce: add defer=True to the reduce node so it sees all N branch results, not just the first one
- →Consensus: add defer=True to the decide node so all evaluators write their votes before the vote is counted
- →Cost: execution time is always bounded by the slowest parallel branch
- →Known risk: in complex graphs with Command routing or multiple defer nodes, spurious re-execution can occur (GitHub #6005)
- →Streaming incompatibility: defer=True blocks all output until every branch finishes — incompatible with real-time partial result delivery
Should You Use Deferred Nodes?
Deferred nodes solve one specific problem: a join node fires too early, before all parallel branches have written their results to state. If that's not your problem, defer=True adds overhead with no benefit.
| Situation | Use defer=True? | Why |
|---|---|---|
| Reduce node reads from N parallel Send() branches | Yes | Without it, reduce may fire after branch 1 and see only partial state |
| Consensus: multiple parallel evaluators vote before deciding | Yes | Need all votes present before the decide node runs |
| Node has exactly one upstream predecessor | No | Single-branch — no race condition exists |
| You need to stream partial results to the user as they arrive | No | defer holds all output until every branch finishes |
| Complex graph with Command routing + multiple defer nodes | Test carefully | Known re-execution bugs in multi-hop topologies (GitHub #6005) |
| Time-critical path where the slowest branch is unpredictable | No | You wait for the worst case — consider incremental processing instead |