Global Random Seed
One seed box for the whole workflow — and you never wire it to anything
- applied_seed
Global Random Seed is the most lazily useful node in the ComfyUI Text Processor pack, and that's a compliment. It does exactly what its name says: you drop one node into a workflow, set a seed value, and every literal seed input in that graph - samplers, noise nodes, anything with an input actually named seed, noise_seed, or seed_num - gets that seed applied before the prompt runs. No wires, no links, no applied_seed cables trailing across your canvas. That's the "zero-wire" trick, and it's the whole point.
Why you'd reach for it: you're doing a multi-pass run - img2img into a hires pass, or a batch where every sampler needs to move in lockstep - and you're tired of tabbing through six KSamplers to keep their seeds in sync. Or you want to advance everything by one with a single click between prompts. This is the node that makes "same seed, whole pipeline" a one-setting operation. Think of it as the seed-farming tool from the KB's sampling lore (converging samplers: same seed, same result) applied to an entire graph at once.
How it actually works
Here's the part that's easy to mistrust: the node has no connections going in or out that matter, yet it still does real work. That's because it doesn't run like a normal node at all. On load, the pack registers a handler with ComfyUI's prompt server (the source calls add_on_prompt_handler). Every time you submit a prompt, that handler rewrites the prompt JSON before execution: it finds the controller, computes the applied seed, walks every node in the graph, and replaces the literal integer values of any input named seed, noise_seed, or seed_num with bounded seeds.
The careful bits matter here. Only literal integers get rewritten - if a seed input is wired to another node, or is a boolean, it's left alone. And the node only changes inputs it recognizes by name; it doesn't try to infer arbitrary third-party node schemas. If you have multiple Global Random Seed nodes in one prompt, the lowest node ID wins and the others are ignored - one controller per prompt, no arguments.
The inputs that matter
Most of the surface is one small enum cluster:
value- the current seed, entered as an exact unsigned decimal string. This is the one you'll actually touch.queue_action- how the controller advances between prompts:fixed(stays put),increment/decrement(step by one, wrapping within the selected width), orrandomize.distribution- how one applied base seed fans out to your targets.samegives every target the identical seed;increment/decrementoffset one bounded value per target;randomizegives each target its own independent seed.seed_width-uint32(0 to 4,294,967,295) is the safe default.uint53goes up to 9,007,199,254,740,991, the largest range JavaScript numeric widgets can display exactly.timingcontrols whether the queue action applies before or after this prompt.
The single output is applied_seed (an INT) - the exact seed this run actually applied. It's is_output_node, so it also renders as a readout; hook it up only if some other node genuinely needs the base seed as a value.
Install
Search ComfyUI Manager for ComfyUI Text Processor, install, restart - or:
cd ComfyUI/custom_nodes/
git clone https://github.com/rookiestar28/ComfyUI_Text_Processor.git
pip install -r requirements.txt
Dependencies are light (simpleeval, requests, beautifulsoup4) - no model downloads for this node. The pack needs Python 3.10+ and ComfyUI Core 0.22.3+.
Where people get burned
- The widget won't show your big seed. New configs only expose
uint32/uint53because JS widgets can't display uint64 values exactly. Olduint64workflows still run backend-compatible, but the controller won't stuff a value into a widget that can't render it - if the target widget must show the seed, useuint53. last_seedreadback looks wrong. A target node's owncontrol_before_generate/control_after_generatesetting can advance its visible widget after submission. Set the target control tofixedif you're comparing widget-to-widget withlast_seed.- API callers must resubmit. The server deliberately keeps no per-client continuation state - an API prompt works, but the next submission needs the new
valuefrom you. - It's a range, not a display format: a valid uint32 can have up to ten digits.
If nothing gets assigned, the most likely culprits are a stale install (the prompt-server hook registers on load - restart ComfyUI after updating) or a seed input wired from another node rather than a literal widget.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| value | STRING | 0 | Current seed as an exact unsigned decimal string. |
| seed_width | COMBO | uint32 | uint32 is the safe default; uint53 is the largest JavaScript-safe selectable range. Legacy uint64 workflows remain backend-compatible. |
| timing | COMBO | before_generation | Apply the queue action before or after this prompt. |
| queue_action | COMBO | fixed | How the controller value advances between prompts. |
| distribution | COMBO | same | How one applied seed is distributed across target nodes. |
| last_seed | STRING | 0 | Exact decimal readback of the last applied seed. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| applied_seed | INT | The exact bounded seed applied to this controller run. |