Lazy Switch (obvpm)
The switch that stops the work, not just the node
- on_false
- on_true
- value
Here's the thing that wastes more GPU time than any bad sampler setting: in ComfyUI, bypassing a node does not stop its upstream from running. The nodes before it still execute, produce their values, and hand them to a bypassed node that cheerfully passes them along. If your "disabled" branch was a second sampler chain, you paid for it.
Lazy Switch (obvpm) is the fix. boolean true takes on_true, false takes on_false - and the unselected side isn't executed at all. Not skipped at the output, not short-circuited late: the nodes feeding it never run. If you've been using bypass and wondering why a "disabled" upscale still costs forty seconds, this is why, and this is the node.
Inputs and outputs
boolean- required BOOLEAN, default true. True =on_true, false =on_false.on_true,on_false- optional wildcard inputs. Only the selected one executes; the other may be left unconnected.value- the selected side's value.Nonewhen the selected side is unconnected.
There's no fallback here, and no error either: an unconnected selected side quietly outputs None. That's deliberate - it means a half-wired workflow still queues, and it pairs with the pack's gates, which are happy to receive a None on an optional input.
How the laziness is implemented
Both candidates are declared as lazy inputs, and the node implements check_lazy_status: before execution the engine asks which inputs are needed, and this node answers with exactly one of them - the selected side. Everything upstream of the unanswered side is pruned from that run. The implementation is careful about one detail: if the selected side has no link at all, it asks for nothing, because requesting a lazy input that isn't connected is a hard engine error. So a disconnected on_false with boolean false gives you None, not a crash.
Two more behaviours that come out of this design:
- Muted branches can be picked back up. If an optional gate in
mutemode killed a path, selecting the other side of this switch continues the workflow normally - the mute blocked the data, it didn't break the nodes. - Automatic switching. Wire a gate's
presentoutput intobooleanand the switch routes itself. Reference image connected → take the reference pipeline. Not connected → take the plain one. No manual toggle, no duplicate workflow.
What lazy doesn't fix
Output nodes. A Preview Image or Save Image on the unselected side still fires. Every OUTPUT_NODE is an execution root - nothing reaches it through a wire, so there's no evaluation for laziness to prune. The pack's own Mute node is the answer there, and it's worth knowing which of the two you're missing, because it's an easy thing to misdiagnose.
Required inputs downstream. value can be None. If it lands on a required socket, you get an error - lazy routing doesn't make consumers tolerant; that's what bypass-aware optional inputs are for.
One value per branch
value is a single wildcard socket. A branch that needs to carry a model, a clip and a latent needs three switches, or one switch carrying a Bundle - which is the pattern this pack is built around: pack the branch's values with Bundle, switch one wire, unpack with Unbundle. Laziness survives it end to end, because the Bundle sits on the branch.
Install
ComfyUI Manager → search comfyui-obvpm (the pack title), or:
cd ComfyUI/custom_nodes
git clone https://github.com/chanon/comfyui-obvpm
Restart. Category obvpm/switches; a node-menu search for obvpm lists everything in the pack. No Python dependencies - the pyproject.toml declares none deliberately, since its imports already ship with ComfyUI. All node ids carry the (obvpm) suffix since 0.2.0, which resolved a class-id clash with another pack; pre-0.2.0 workflows migrate automatically when opened.
For ganged versions of the same idea, the pack also ships Lazy Switch 2 Values and Lazy Switch 3 Values - same mechanism, two or three wires flipping on one boolean.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| boolean | BOOLEAN | true | Selects which side to execute and output: true = on_true, false = on_false. |
| on_falseopt | * | Output when boolean is false. Only executes while selected; may be left unconnected. | |
| on_trueopt | * | Output when boolean is true. Only executes while selected; may be left unconnected. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| value | * | The selected side's value. None when the selected side is unconnected. |