Nodes/jlc-comfyui-nodes/ JLC ControlNet Orchestrator (Advanced)
ComfyUI Node

 JLC ControlNet Orchestrator (Advanced)

Multi-ControlNet without the chain

By Damkohler·Created 6 months ago·Updated 3 days ago· 25
 JLC ControlNet Orchestrator (Advanced)
  • positive
  • negative
  • vae
  • image_01
  • image_02
  • image_03
  • image_04
  • image_05
  • image_06
  • image_07
  • image_08
  • CONDITIONING
  • CONDITIONING
slot_count3
controlnet_cache_size2
control_net_name_01
strength_011.00
start_010.000
end_011.000
weight_011.00
control_net_name_02
strength_021.00
start_020.000
end_021.000
weight_021.00
control_net_name_03
strength_031.00
start_030.000
end_031.000
weight_031.00
control_net_name_04
strength_041.00
start_040.000
end_041.000
weight_041.00
control_net_name_05
strength_051.00
start_050.000
end_051.000
weight_051.00
control_net_name_06
strength_061.00
start_060.000
end_061.000
weight_061.00
control_net_name_07
strength_071.00
start_070.000
end_071.000
weight_071.00
control_net_name_08
strength_081.00
start_080.000
end_081.000
weight_081.00
alpha1.00

This is the flagship of JLC's ControlNet family, and it's the node the pack's README points new users to first. JLC ControlNet Orchestrator (Advanced) is a single node that replaces the whole stack - loaders, Apply nodes, and most of the wiring - for running multiple ControlNets at once. Up to eight slots, each with its own model dropdown, hint image, strength, activation window, and weight, all fused into one conditioning stream.

The pitch isn't convenience, though that's real. It's how the fusion happens. Where ComfyUI natively evaluates chained ControlNets recursively - think A(B(C(x))) - the JLC core evaluates each ControlNet independently against the same sampler state and combines the outputs explicitly: roughly A(x) + B(x) + C(x), with weights. Fewer repeated passes, less accumulated memory pressure, and behavior that's actually predictable. On a ControlNet-heavy Flux workflow, that's the difference between a graph you trust and one you babysit.

How it works

Each slot gets prepared as an isolated per-run copy of its base model (set_cond_hint() with your image, strength, and range), and the results are aggregated as Σ W_i·C_i(x). The weight per slot is w_i · alpha^i, where alpha is an order-bias dial:

  • alpha = 1.0 is neutral - slots contribute in proportion to their weight, order-independent.
  • alpha < 1 favors earlier slots; alpha > 1 favors later ones. Negative alpha flips influence by position.

Model loading is handled internally with a shared cache, so if three slots use the same ControlNet file, it loads once and each slot gets its own conditioned copy. The SHARE_PREVIOUS selector option lets a slot reuse whatever named model was chosen just before it - handy when you want the same ControlNet at different strengths or windows.

There's also a genuinely good safety habit here: strict preflight. The node validates every active slot before it loads any model. A slot with a model selected, meaningful strength, meaningful weight, and a non-empty range, but no connected hint image, raises a clear error up front instead of failing mid-sampling.

Inputs that matter

  • positive / negative - your conditioning in and out (two CONDITIONING outputs).
  • vae - needed for hint encoding.
  • slot_count (1–8, default 3) - how many slots are active. Backend ignores anything above it.
  • controlnet_cache_size - the shared cache capacity. Set to 0 to avoid keeping resident cached ControlNets between runs.
  • Per slot: control_net_name (DISABLED / SHARE_PREVIOUS / a model), image, strength (0–10), start/end (0–1 activation window), weight (-10 to 10, the fusion weight).
  • alpha - the order-bias knob above.

Installing it

Ships in jlc-comfyui-nodes:

cd ComfyUI/custom_nodes
git clone https://github.com/Damkohler/jlc-comfyui-nodes.git

Restart ComfyUI, or install "jlc-comfyui-nodes" from ComfyUI Manager. No Python dependencies. Your ControlNet model files go in the normal models/controlnet folder and show up in the dropdowns. A starter workflow (drag-and-drop PNG) is included in the repo's assets/workflows/ if you want a known-good starting point.

Where people get burned

  • "Missing image" errors are the preflight working. Connect the image, set the selector to DISABLED, zero the strength/weight, or empty the activation range. The error is telling you exactly which slot is under-specified.
  • SHARE_PREVIOUS needs a prior named model. Slot 1 can't share a selection that was never made - put a named model in an earlier slot first.
  • Slow? Check --lowvram. The author's investigation pinned a multi-hour collapse on forced --lowvram (destructive partial unload/reload cycles), not on the fusion math. Normal VRAM mode with DynamicVRAM is the tested baseline.
  • One ControlNet at weight 1.0 goes native. A single effective control routes through ComfyUI's own path because it's mathematically equivalent. Not a bug.

Context for the skeptical: this is one developer's project (J. L. Córdova), announced with benchmarks on a 16 GB RTX 4090 laptop, and the speedup claims are his own measurements. The idea - flatten recursive ControlNet chains into independent weighted evaluation - is sound and the implementation is careful and heavily documented. Try it with the included workflow before you rip out your existing setup.

Categoryconditioning/controlnet

Inputs (54)

NameTypeDefaultDescription
positiveCONDITIONING
negativeCONDITIONING
vaeVAE
slot_countoptINT31–8Number of visible/active internal ControlNet slots. Backend ignores slots above this count.
controlnet_cache_sizeoptINT20–10Shared JLC ControlNet cache capacity. 0 means evict/prevent resident cached ControlNets.
control_net_name_01optCOMBOControlNet model for this slot. SHARE_PREVIOUS reuses the last selected model.
image_01optIMAGEControl image for this slot. A disconnected socket or runtime None (including a DISABLED/hidden aux-wrapper output) disables only this slot.
strength_01optFLOAT1.000–10
start_01optFLOAT0.0000–1
end_01optFLOAT1.0000–1
weight_01optFLOAT1.00-10–10
control_net_name_02optCOMBOControlNet model for this slot. SHARE_PREVIOUS reuses the last selected model.
image_02optIMAGEControl image for this slot. A disconnected socket or runtime None (including a DISABLED/hidden aux-wrapper output) disables only this slot.
strength_02optFLOAT1.000–10
start_02optFLOAT0.0000–1
end_02optFLOAT1.0000–1
weight_02optFLOAT1.00-10–10
control_net_name_03optCOMBOControlNet model for this slot. SHARE_PREVIOUS reuses the last selected model.
image_03optIMAGEControl image for this slot. A disconnected socket or runtime None (including a DISABLED/hidden aux-wrapper output) disables only this slot.
strength_03optFLOAT1.000–10
start_03optFLOAT0.0000–1
end_03optFLOAT1.0000–1
weight_03optFLOAT1.00-10–10
control_net_name_04optCOMBOControlNet model for this slot. SHARE_PREVIOUS reuses the last selected model.
image_04optIMAGEControl image for this slot. A disconnected socket or runtime None (including a DISABLED/hidden aux-wrapper output) disables only this slot.
strength_04optFLOAT1.000–10
start_04optFLOAT0.0000–1
end_04optFLOAT1.0000–1
weight_04optFLOAT1.00-10–10
control_net_name_05optCOMBOControlNet model for this slot. SHARE_PREVIOUS reuses the last selected model.
image_05optIMAGEControl image for this slot. A disconnected socket or runtime None (including a DISABLED/hidden aux-wrapper output) disables only this slot.
strength_05optFLOAT1.000–10
start_05optFLOAT0.0000–1
end_05optFLOAT1.0000–1
weight_05optFLOAT1.00-10–10
control_net_name_06optCOMBOControlNet model for this slot. SHARE_PREVIOUS reuses the last selected model.
image_06optIMAGEControl image for this slot. A disconnected socket or runtime None (including a DISABLED/hidden aux-wrapper output) disables only this slot.
strength_06optFLOAT1.000–10
start_06optFLOAT0.0000–1
end_06optFLOAT1.0000–1
weight_06optFLOAT1.00-10–10
control_net_name_07optCOMBOControlNet model for this slot. SHARE_PREVIOUS reuses the last selected model.
image_07optIMAGEControl image for this slot. A disconnected socket or runtime None (including a DISABLED/hidden aux-wrapper output) disables only this slot.
strength_07optFLOAT1.000–10
start_07optFLOAT0.0000–1
end_07optFLOAT1.0000–1
weight_07optFLOAT1.00-10–10
control_net_name_08optCOMBOControlNet model for this slot. SHARE_PREVIOUS reuses the last selected model.
image_08optIMAGEControl image for this slot. A disconnected socket or runtime None (including a DISABLED/hidden aux-wrapper output) disables only this slot.
strength_08optFLOAT1.000–10
start_08optFLOAT0.0000–1
end_08optFLOAT1.0000–1
weight_08optFLOAT1.00-10–10
alphaoptFLOAT1.00-2–2Order bias. 1.0 = neutral. <1 favors earlier slots. >1 favors later slots. Negative values invert influence.

Outputs (2)

NameTypeDescription
CONDITIONINGCONDITIONING
CONDITIONINGCONDITIONING