Seed Stepper π±
Never repeat a seed you've already used β unless you want to
- seed
- history_count
- summary
ComfyUI's built-in seed controls are dumb in a specific way: randomize rolls a fresh seed every run and promptly forgets which ones it used. Fine for one-offs, maddening for a batch - you get 30 images, 15 of them from seeds you've already seen. Seed Stepper π± is the one that remembers. It tracks a persistent history of the seeds it's handed out across queue runs and picks the next one according to a mode you choose: increment, random-but-never-repeat, or cycle through a hand-picked list.
The "never repeat" mode is the headline. If you're farming a prompt across many runs, this guarantees every image in the batch came from a seed you haven't rendered before, so you're not wasting GPU cycles re-rolling the same latent noise.
How it works
State lives in a JSON history file, output/<history_id>.seedhistory.json (default history_id is "default"). That file is also why the node forces itself to re-execute every queue run - its real state is on disk, not in its widgets, so ComfyUI's cache has to be bypassed or it would skip and hand you the same seed.
The three modes:
- increment - same idea as the pack's Batch Counter (
base_seed + count * seed_step), but it also logs every seed used, giving you a readable audit trail of exactly which seed produced which run. - random_no_repeat - picks a random seed in
[0, max_seed]that isn't in the history file, retrying up to 1000 times on collision. Oncehistory_limit(default 1000) seeds are recorded, the oldest drop off so the file doesn't grow forever. - cycle_list - steps through
seed_list(comma-separated integers, default1,2,3,4,5) in order, wrapping at the end. Ignores history and randomness entirely - deterministic playback of a specific hand-picked sequence.
The inputs that matter
mode, history_id, base_seed + seed_step (for increment), max_seed + history_limit (for random_no_repeat), and seed_list (for cycle_list). Outputs are seed (wire it into your KSampler's seed input - convert the widget to an input first), history_count, and summary. Different history_ids run independent histories side by side, which is how you keep two experiments from contaminating each other's "used" lists.
One honest note on placement: this node uses CATEGORY = "TensorVizion/Sampling", a submenu the pack's other Sampling nodes don't share (they live under Model Utilities). It's a deliberate split - this is a standalone utility, not a core-sampler wrapper - but it means searching "seed" may not be where you expect.
Installing it
Part of the OmniNodes pack:
cd ComfyUI/custom_nodes/
git clone https://github.com/TensorVizion/OmniNodes
Restart ComfyUI (or search "OmniNodes" in ComfyUI Manager). No extra dependencies - standard library plus ComfyUI's folder_paths. If it doesn't appear after install, restart completely and check the terminal for [OmniNodes] β
Loaded lines.
The community's "change one variable, keep everything else fixed" discipline is exactly why this node exists: when you're farming a batch of prompts, the seed should be the only thing that changes between runs, and it should never silently repeat itself. That's what this node enforces for you.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| mode | COMBO | 3 options: increment, random_no_repeat, cycle_list | |
| history_id | STRING | default | β |
| base_seed | INT | 00β18446744073709550000 | β |
| seed_step | INT | 10β1000000 | β |
| max_seed | INT | 42949672951β18446744073709550000 | β |
| history_limit | INT | 100010β100000 | β |
| seed_list | STRING | 1,2,3,4,5 | β |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| seed | INT | β |
| history_count | INT | β |
| summary | STRING | β |