Nodes/comfyui-svdint4/Stage Barrier
ComfyUI Node

Stage Barrier

Make ComfyUI do the expensive stuff in the order you meant

By wjie98·Created 2 months ago·Updated 3 days ago· 2
Stage Barrier
  • values
  • value_0
  • value_1
  • value_2
  • value_3
  • value_4
  • value_5
  • value_6
  • value_7
  • value_8
  • value_9
  • value_10
  • value_11
  • value_12
  • value_13
  • value_14
  • value_15
  • value_16
  • value_17
  • value_18
  • value_19
  • value_20
  • value_21
  • value_22
  • value_23
  • value_24
  • value_25
  • value_26
  • value_27
  • value_28
  • value_29
  • value_30
  • value_31
  • value_32
  • value_33
  • value_34
  • value_35
  • value_36
  • value_37
  • value_38
  • value_39
  • value_40
  • value_41
  • value_42
  • value_43
  • value_44
  • value_45
  • value_46
  • value_47
  • value_48
  • value_49
  • value_50
  • value_51
  • value_52
  • value_53
  • value_54
  • value_55
  • value_56
  • value_57
  • value_58
  • value_59
  • value_60
  • value_61
  • value_62
  • value_63
  • value_64
  • value_65
  • value_66
  • value_67
  • value_68
  • value_69
  • value_70
  • value_71
  • value_72
  • value_73
  • value_74
  • value_75
  • value_76
  • value_77
  • value_78
  • value_79
  • value_80
  • value_81
  • value_82
  • value_83
  • value_84
  • value_85
  • value_86
  • value_87
  • value_88
  • value_89
  • value_90
  • value_91
  • value_92
  • value_93
  • value_94
  • value_95
  • value_96
  • value_97
  • value_98
  • value_99
stage0

ComfyUI executes nodes in dependency order, and that's usually right. But "usually" is doing a lot of work when your workflow is model-heavy. Say you're running MiniMax H3: you want all the reference/VAE preparation to finish, then all the semantic conditioning, then all the sampling - grouped into phases so the big model loads once and stays resident instead of being shuffled on and off the GPU between every branch. The stock scheduler doesn't think in phases. That's what Stage Barrier is for: a rendezvous point that forces every barrier at the same stage to complete before downstream work is released.

It's really two tools in one node. It's a pass-through: connect up to 100 arbitrary ComfyUI values (autogrow inputs value_0 through value_99) and each is forwarded to the matching output, untouched. And it's an execution-order gate: the stage widget (an integer, 0 by default) is the global ordering key, and every reachable barrier with a smaller stage must finish before any barrier at a larger stage releases its downstream work. It never bypasses a data dependency - this is scheduling, not graph-rewriting.

How it actually works

The node's execute is almost boringly simple: it forwards values and logs which stage it hit. The magic lives in the pack's runtime, which wraps ComfyUI's ready-node picker (ExecutionList.ux_friendly_pick_node) so the scheduler chooses which ready node runs next, barrier-first. Two details are worth knowing because they're the difference between "cool" and "it deadlocked":

  • Same-stage rendezvous. Barriers at the same stage synchronize with each other before anything downstream is released, so you can fan a phase across several branches and guarantee they all arrive.
  • Priority inheritance. If a high-stage barrier feeds a low-stage one, it temporarily inherits the lower priority. Stage order opposing data flow can't deadlock your graph - a stage-4 barrier that a stage-1 barrier depends on quietly counts as stage 1.

There's one more virtue: because stage ordering only reorders ready nodes, it never blocks the executor thread and never hides a real cycle. If you build an actual dependency loop, the pack falls back and lets ComfyUI emit its normal cycle diagnostic instead of hanging forever.

Using it

cd ComfyUI/custom_nodes
git clone https://github.com/wjie98/comfyui-svdint4

or ComfyUI Manager → search "Turing Utils", restart. Pure logic - no kernel, no models, no compile. The README's suggested H3 rhythm: stage 0 barriers after reference/VAE preparation, stage 1 after semantic conditioning, stage 2 after sampling. That maps to keeping model-heavy branches grouped by residency phase.

Two practical rules. First, keep stage as a widget, not a converted input - the tooltip is explicit that the scheduler needs to read it before executing upstream nodes. Second, if your ComfyUI build doesn't expose a compatible ExecutionList picker, the pack logs a warning and disables ordering: barriers still pass values through, you just lose the stage guarantee. Check the log if barriers ever stop mattering.

Where it fits in your head: most ComfyUI users never need this. If your workflows are small or your GPU loads models fast, it's an extra moving part for a problem you don't have. But once you're doing multi-branch H3 or Wan work where offload order decides whether a run fits in VRAM at all, a stage barrier is the difference between watching the model thrash and watching it just work. It's the least glamorous node in this pack and, for that crowd, one of the most useful.

CategoryTuring Utils/logic

Inputs (2)

NameTypeDefaultDescription
stageINT00–2147483647Phase label within an automatically inferred dependency round. Use values such as 0=prepare, 1=sample, 2=decode and reuse them in dependent rounds. This must remain a widget so the scheduler can plan it before executing upstream nodes.
valuesoptCOMFY_AUTOGROW_V3Connect any number and mixture of ComfyUI values. Each input is forwarded to the matching output without copying it.

Outputs (100)

NameTypeDescription
value_0*
value_1*
value_2*
value_3*
value_4*
value_5*
value_6*
value_7*
value_8*
value_9*
value_10*
value_11*
value_12*
value_13*
value_14*
value_15*
value_16*
value_17*
value_18*
value_19*
value_20*
value_21*
value_22*
value_23*
value_24*
value_25*
value_26*
value_27*
value_28*
value_29*
value_30*
value_31*
value_32*
value_33*
value_34*
value_35*
value_36*
value_37*
value_38*
value_39*
value_40*
value_41*
value_42*
value_43*
value_44*
value_45*
value_46*
value_47*
value_48*
value_49*
value_50*
value_51*
value_52*
value_53*
value_54*
value_55*
value_56*
value_57*
value_58*
value_59*
value_60*
value_61*
value_62*
value_63*
value_64*
value_65*
value_66*
value_67*
value_68*
value_69*
value_70*
value_71*
value_72*
value_73*
value_74*
value_75*
value_76*
value_77*
value_78*
value_79*
value_80*
value_81*
value_82*
value_83*
value_84*
value_85*
value_86*
value_87*
value_88*
value_89*
value_90*
value_91*
value_92*
value_93*
value_94*
value_95*
value_96*
value_97*
value_98*
value_99*