Lazy Execution
The node that makes sequential execution and gated loops actually work in ComfyUI
- value
- signal
- value
LazyExecution is a gate: it passes its value input through to its value output, but only once a separate signal input has resolved. Downstream nodes that read its output don't run until the signal arrives, and if the signal is an ExecutionBlocker - the special ComfyUI value that means "don't run downstream" - that block propagates through and skips the whole branch. One tiny node, and it's the difference between "I hope ComfyUI runs these in the right order" and "I have explicitly sequenced my graph."
ComfyUI executes nodes based on data dependencies, not left-to-right placement. That's normally exactly what you want, but sometimes you need sequencing - "run generation B only after generation A finished" - or you want to build a loop where a branch stays dead until some condition clears. Those are this node's two jobs.
How it works
Mechanically it's almost insultingly simple: execute(value, signal) just returns value. The magic is entirely in when ComfyUI decides to run it. Because value is forwarded only after signal resolves, anything consuming the output is transitively dependent on signal. Feed it an ExecutionBlocker from something like Api Collect or Grok Collect - which block downstream while their remote job isn't ready - and the block flows through LazyExecution to gate everything after it.
The pack's own example is the classic pattern: gate an OpenAI Inference + Api Submit chain on Api Collect, so a new remote job is only built once the previous one has been collected. That's a polling loop with real state, and it would be a miserable pile of custom scripting without this node.
There's a subtle, genuinely useful detail in how the inputs are ordered: value is the first input, so when you mute (bypass) the node, ComfyUI passes value straight through and ignores signal. That's the documented trick for cold-starting a gated loop - if Api Collect has no job yet and keeps emitting blockers forever, mute the gate for one run to fire the first submit, then unmute to resume normal gating.
Inputs and output
value- ANY type; whatever you want to pass through once the gate opens.signal- ANY type; the gate. The pass-through happens only after this resolves, and an ExecutionBlocker here blocks everything downstream.
Output: value, the forwarded input. One output, same type as the input.
Install
Part of ComfyUI-Alchemine-Pack:
cd ComfyUI/custom_nodes
git clone https://github.com/alchemine/comfyui-alchemine-pack
pip install -r requirements.txt
Or via ComfyUI Manager (search "ComfyUI-Alchemine-Pack"). Only dependency is python-dotenv; no models.
Common issues
The confusion is usually about what "resolves" means. An ExecutionBlocker is not a value that flows through - it halts the branch, and that's the point, but if you're expecting to see the blocked value downstream you'll be baffled. The other trap is forgetting that muting bypasses the gate entirely: if you mute it to prime a loop and forget to unmute, your "gate" is now just a wire and your loop will happily stack jobs. The pack names this exact behavior in its docs, so it's a feature - just remember to flip it back.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| value | * | — | |
| signal | * | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| value | * | — |