Random Float
Jitter CFG and Denoise Between Runs with Random Float
- VALUE
- RANGE_FROM
- RANGE_TO
- PRECISION
- STEP
The seed widget on a KSampler only randomizes the noise. When you actually want to vary a parameter between runs - bump denoise around 0.5, wobble your CFG, nudge a LoRA strength while keeping it on a sane grid - ComfyUI makes you build it yourself out of a seed, a math node, and prayers. Random Float is the shortcut: pick a range, get a decimal back every run, wire it into anything whose widget you've converted to an input. It's the decimals-flavored sibling of Random Int, from the same tiny two-node comfyui-random-nodes pack.
That pack is worth knowing as a whole: pure Python standard library, no pip dependencies, no model downloads, MIT license, and written against ComfyUI's new V3 backend API (comfy_api.latest) rather than the old NODE_CLASS_MAPPINGS style. Brand-new (v1.0.0, mid-2026) and minimal on purpose - the author's stated philosophy is one role per node, no feature creep.
How it works
The generation is random.uniform(range_from, range_to), and then two things happen that make this node actually useful instead of a rounding function in a trench coat:
- Step snapping. Set
stepto 0.05 and the result lands on the nearest 0.05 grid point measured fromrange_from- perfect for LoRA strengths people actually use, or anything where "random to 7 decimals" is noise rather than variation.stepof 0 (the default) means no snapping. - Precision rounding.
precisioncontrols decimal places, default 2, minimum 1 (the node refuses values below that). So you get a clean0.73, not0.7265841930201.
The range behaves the same way as its integer cousin: inverted bounds are swapped for you, and there's no seed input - this is genuinely random per run, not reproducible. When the randomized checkbox is off, it returns the stored value rounded to precision, which is how you freeze a number you liked.
The inputs and outputs that matter
Four inputs are real sockets; two are controls embedded on the node body:
range_from/range_to- the min and max (defaults 0 and 1). Both are wireable, so another node can shift your jitter window dynamically.precision- decimal places, as above.step- the snap grid. This is the input that separates "random float" from "random float you'd actually put in a workflow."randomized- checkbox on the node, off by default. Off returns the stored value; on rolls fresh every run. This is what you want for batch-to-batch variation.value- the stored result, updated after each run so the node always shows its last roll.
The node face also carries two buttons: New random value rolls once and flips randomized off, and Use current: N restores the last result. Yes, that split confuses everyone: the button means "roll once, freeze it," the checkbox means "reroll every single run." Different cadences for different jobs.
Outputs: VALUE is the number you feed downstream. RANGE_FROM, RANGE_TO, PRECISION, and STEP are all passthroughs echoing their inputs - useful when you don't want to duplicate wires to share the range elsewhere.
Installing it
ComfyUI Manager, search comfyui-random-nodes, or clone it manually:
cd ComfyUI/custom_nodes
git clone https://github.com/Mistralys/comfyui-random-nodes.git
Restart ComfyUI and it lives under Add Node → random → Random Float. No requirements to pip-install, nothing to download. The one real requirement: the pack is V3-API only, so your ComfyUI needs to be new enough to ship comfy_api.latest. On an older build it simply won't appear - that's the compatibility cost of a pack that bet on the new API.
Where people get burned
Aside from the button-versus-checkbox gotcha above: with randomized on, the node deliberately re-executes every run (it returns a time-based fingerprint to break ComfyUI's cache), so everything downstream re-runs too. Fine for a denoise jitter; wasteful if you route an expensive node's value through it. And remember step snapping anchors at range_from and clamps to range_to - set the step and you'll occasionally get a roll that's a surprise if you didn't notice your range isn't a clean multiple. Small pack, sharp edges are small.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| range_from | FLOAT | 0.00 | Minimum float value to generate. |
| range_to | FLOAT | 1.00 | Maximum float value to generate. |
| precision | INT | 2 | Number of decimal places. |
| step | FLOAT | 0.00 | Snap generated values to this step grid. 0.0 means no stepping. |
| value | FLOAT | 0.00 | The randomized value. Reused when 'randomized' is off. |
| randomized | BOOLEAN | false | Whether to generate a new random value on the next run. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| VALUE | FLOAT | The generated (or stored) float value. |
| RANGE_FROM | FLOAT | Passthrough of the input value. |
| RANGE_TO | FLOAT | Passthrough of the input value. |
| PRECISION | INT | Passthrough of the input value. |
| STEP | FLOAT | Passthrough of the input value. |