⚙️ Batch Processor
Run your workflow N times and hand it a counter
- any
- any
- index
- total
- remaining
Sometimes you don't want one image - you want "run this exact workflow five times and let me look at all of them." Core ComfyUI lets you do that by batching latents, but that breaks the moment your workflow has a step that doesn't batch cleanly, or when each pass needs its own fresh random seed. The ⚙️ Batch Processor (class Logic_Looper) is the "just run the whole thing again" answer: you set a total, hit Queue, and it re-submits the workflow that many times, exposing a counter so each pass knows where it is.
The mechanism is worth understanding, because it's not a loop in the usual sense - there's no cycle in the graph. The node keeps a tiny bit of state per node instance (a dict keyed by the node's internal ID), and every execution it reports three numbers back to the frontend: index (which pass you're on, 0-based), total, and remaining. That progress report is what makes ComfyUI auto-queue the next run, and it keeps doing it until index reaches total, then stops and resets its state. The result: N sequential runs of your whole graph, with a visible progress bar, and a counter you can read.
That counter is the whole point, because a loop that just repeats identical work is useless. You feed the outputs into the rest of your workflow: index can drive a seed (add it to a base seed so every pass is different), a filename suffix, or a select on a Switcher to vary the LoRA per pass. There's also an any pass-through input/output - a wildcard socket you can thread a value through untouched, which mostly exists so the node participates in data flow without you having to look for a disconnected counter elsewhere.
Inputs: total (INT, 1–9999, default 3) and optional any. Outputs: any (pass-through), index, total, remaining - all INT. The always-rerun trick (IS_CHANGED → NaN) is what makes each pass fire instead of ComfyUI deciding nothing changed and skipping.
Now the honest caveats, because this node has real trade-offs and you should hear them before you build a 200-pass batch on it.
It re-queues the whole workflow. Every pass re-runs every node upstream of the Looper, including loaders and anything else you thought you'd "already done." There's no in-memory loop, so a pass is as expensive as a full manual run. Cheap graphs: great. A 30-second generation: you're committing to 30 × N.
State is per-node, and it resets. The counter lives in the class, not in your saved workflow. If you stop mid-batch and hit Queue again fresh, it restarts from zero - which is usually what you want ("next manual run automatically resets," as the README says), but it means you can't pause and resume a batch from where it left off.
A dirty node poisons the graph. Since the Looper is always dirty, anything it feeds re-runs every pass - which, combined with the first point, is the entire loop. That's by design. Just don't be surprised that "the sampler runs N times" is exactly what you asked for.
There are other looping approaches in the ecosystem - graph-level iteration packs, and the newer subgraph features in core ComfyUI - but this one is refreshingly simple: set a number, click queue, count the results. For "vary the seed and give me five to pick from," it does the job without ceremony.
Install is pack-wide:
cd ComfyUI/custom_nodes
git clone https://github.com/playboy-dongan/ComfyUI-Logic-nodes
or ComfyUI Manager → search "ComfyUI-Logic-nodes" → restart. No models, no extra dependencies.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| total | INT | 31–9999 | — |
| anyopt | * | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| any | * | — |
| index | INT | — |
| total | INT | — |
| remaining | INT | — |