ComfyUI Node

Hold Counter

Keep a Load Image on one image for several runs

By mitch-avis·Created 4 months ago·Updated 2 months ago· 3
Hold Counter
    • index
    • index_str
    runs_per_index1
    min_index0
    max_index1
    modeloop
    format{}
    reset_trigger0

    Hold Counter is one of those nodes you don't know you need until you're sitting there, for the fifth time, manually re-typing the same batch index because you want three different seeds on the same image before moving to the next one. It's a tiny integer counter that emits an index, holds it for however many queue runs you ask, then advances. Wire it into the index input of a Load Image (Batch) node and the whole "several seeds per image" workflow becomes automatic. It won't generate anything, but it'll save you a small pile of boredom.

    What it actually does

    Under the hood it's dumber than you think and that's the point. Each Hold Counter node keeps its own counter state, keyed by ComfyUI's internal unique_id. Every time you hit Queue, it returns the current index and increments an internal run counter. It only advances the index once its run counter crosses your runs_per_index threshold. So with runs_per_index = 3, index 0 comes out three runs in a row, then 1, then 2, and so on.

    Two details make it actually work instead of being a toy. First, the node is an output node that overrides IS_CHANGED to always return nan - that's the trick that forces ComfyUI to execute it on every queue run. Without that, ComfyUI caches results and your counter never moves. Second, it caches the computed index for the whole hold window, so random mode rolls once and then holds that same value for the full runs_per_index window instead of re-rolling every run.

    The inputs that matter

    You'll set maybe three of these:

    • runs_per_index - how many consecutive runs each index is held. Default 1.
    • min_index / max_index - the inclusive range you walk. Defaults are 0 and 1. Order doesn't matter; if you swap them it fixes itself.
    • mode - how it advances: loop (wrap around), clamp (hit max, then stay forever), pingpong (bounce 0,1,2,3,4,3,2,1…), random, or shuffle (a random permutation per pass).

    format is a Python-style format string applied to the string output - "{:04d}" gives you 0007, "frame_{:03d}" gives frame_007. If you feed it a bad template it quietly falls back to str(index) instead of exploding mid-workflow, which is the right call. There's also a hidden reset_trigger input you don't touch by hand; the Reset button in the node body bumps it, and it only rewinds that node's counter.

    What comes out

    Two outputs: index (INT) and index_str (STRING). index is what you'd wire into a Load Image (Batch) index input or anywhere else that wants a number. index_str is the formatted version, handy for things like a filename prefix on Save Image. You can use either or both.

    Installing it

    This is the easiest part of the whole pack: there are no Python dependencies beyond ComfyUI itself and no model files to download. Through ComfyUI Manager, open Manager → Install Custom Nodes, search ComfyUI-HoldCounter, install, restart. Or by hand:

    cd ComfyUI/custom_nodes
    git clone https://github.com/mitch-avis/ComfyUI-HoldCounter.git
    

    Then restart ComfyUI. It shows up under utils → Hold Counter, and the repo ships a ready-to-import example workflow in workflows/hold_counter_basic.json if you want a working graph to poke at.

    The gotchas

    Two things trip people up. First, counter state lives for the ComfyUI session only - restart ComfyUI and every counter is back to zero, so don't rely on it surviving a reboot mid-batch. Second, state is per-node: multiple Hold Counters in one workflow advance independently, which is what you want when you're driving two Load Image nodes from the same run. One historical wart worth knowing: an older release sometimes dropped your format string and emitted raw integers instead. If your index_str comes out as "2" instead of "frame_0002", update the node - that bug's been fixed. It's a small, honest tool, and for batch automation it's one of those things you'll reach for constantly once you've used it once.

    Categoryutils

    Inputs (6)

    NameTypeDefaultDescription
    runs_per_indexINT11–1000
    min_indexINT00–1000000
    max_indexINT10–1000000
    modeCOMBOloop5 options: loop, clamp, pingpong, random, shuffle
    formatSTRING{}
    reset_triggeroptINT00–2147483647

    Outputs (2)

    NameTypeDescription
    indexINT
    index_strSTRING