TL;DR: A Stable Diffusion step is one pass of iterative denoising, not a rendering pass. Stability's hosted image endpoints expose no steps parameter at all as of August 27, 2026, so the setting now lives in the legacy v1 API and in local tooling. The right count depends on your sampler, and distilled models are built around four.
What is a step in Stable Diffusion?
One iteration of denoising. The model begins with a latent tensor full of random noise and, on each step, predicts what that noise looks like and subtracts a portion of it. Repeat, and a picture resolves out of static.
Two words in that sentence do the work. Iterative: every step is a full forward pass of the model over the whole latent, so nothing is being drawn in stages. Denoising: the picture is not getting sharper or larger, it is getting less noisy. Steps have nothing to do with resolution.
ComfyUI states both halves in its node tooltips. The steps widget reads "The number of steps used in the denoising process." The scheduler widget next to it reads "The scheduler controls how noise is gradually removed to form the image."
That second tooltip points at the mechanism that most articles skip. In ComfyUI's sampler code the step count is an input to the scheduler, which returns a ladder of noise levels, and the sampler then walks that ladder:
# comfy/samplers.py
def calculate_sigmas(model_sampling, scheduler_name: str, steps: int) -> torch.Tensor:
handler = SCHEDULER_HANDLERS.get(scheduler_name)
...
return handler.handler(n=steps, sigma_min=..., sigma_max=...)
So a 20-step run is not the first 20 steps of a 50-step run. Changing the count regenerates the whole ladder, and every step lands at a different noise level. That is why a small step change can shift composition, not just detail.
Does Stability's hosted API still have a steps parameter?
For images, no. This is the single biggest gap between what ranks for this query and what is true today.
I pulled Stability's live REST v2beta OpenAPI document on August 27, 2026 and enumerated every request schema. Nineteen hosted image endpoints, zero of them expose steps.
| Endpoint group | Endpoints | Exposes steps? |
|---|---|---|
stable-image/generate (core, ultra, sd3) | 3 | No |
stable-image/edit (inpaint, outpaint, erase, relight, search-and-replace, search-and-recolor, remove-background) | 7 | No |
stable-image/control (sketch, structure, style, style-transfer) | 4 | No |
stable-image/upscale (fast, conservative, creative) | 3 | No |
v2alpha/generation/stable-image (inpaint, upscale) | 2 | No |
audio/stable-audio and audio/stable-audio-2 | 6 | Yes |
The whole accepted body for generate/core is prompt, aspect_ratio, negative_prompt, seed, style_preset and output_format. generate/sd3 adds model, cfg_scale, mode, image and strength.
# Stable Image Core. There is no steps field to send.
curl -f -sS -X POST "https://api.stability.ai/v2beta/stable-image/generate/core" \
-H "authorization: Bearer $STABILITY_API_KEY" \
-H "accept: image/*" \
-F prompt="a cast-iron kettle steaming on a wood stove, cold morning light" \
-F aspect_ratio="3:2" \
-F output_format="webp" \
-o kettle.webp
# SD 3.5 via the sd3 endpoint. cfg_scale and model exist; steps does not.
curl -f -sS -X POST "https://api.stability.ai/v2beta/stable-image/generate/sd3" \
-H "authorization: Bearer $STABILITY_API_KEY" \
-H "accept: image/*" \
-F prompt="a cast-iron kettle steaming on a wood stove, cold morning light" \
-F model="sd3.5-large" \
-F cfg_scale=4 \
-F aspect_ratio="3:2" \
-F output_format="png" \
-o kettle.png
Where steps survives on the hosted platform is audio. The stable-audio-2 schema documents it plainly: "Controls the number of sampling steps." and then, per model, "For stable-audio-2: accepts steps between 30 and 100 (defaults to 50)."
# Stable Audio 2.0 — the base model, 50 steps by default.
curl -f -sS -X POST "https://api.stability.ai/v2beta/audio/stable-audio-2/text-to-audio" \
-H "authorization: Bearer $STABILITY_API_KEY" \
-H "accept: audio/*" \
-F prompt="warm upright piano loop, dusty tape hiss, 82 bpm" \
-F model="stable-audio-2" \
-F steps=50 \
-F cfg_scale=7 \
-F duration=45 \
-o loop.mp3
# Stable Audio 2.5 — distilled. The whole legal range is 4 to 8 steps.
curl -f -sS -X POST "https://api.stability.ai/v2beta/audio/stable-audio-2/text-to-audio" \
-H "authorization: Bearer $STABILITY_API_KEY" \
-H "accept: audio/*" \
-F prompt="warm upright piano loop, dusty tape hiss, 82 bpm" \
-F model="stable-audio-2.5" \
-F steps=8 \
-F cfg_scale=1 \
-F duration=45 \
-o loop-fast.mp3
Where does the steps parameter still exist?
Two places, and both are real.
The v1 REST API. Stability's version 1 reference still documents steps on /v1/generation/{engine_id}/text-to-image with the description "Number of diffusion steps to run.", a default of 30, a minimum of 10 and a maximum of 50. It also documents the one thing v2beta never exposed: a sampler enum of ten values, described as "Which sampler to use for the diffusion process. If this value is omitted we'll automatically select an appropriate sampler for you."
That API is not dead. The v2beta spec's own introduction says services on the older APIs "will continue to be maintained, however they will not receive" new features or parameters, and on August 27, 2026 an unauthenticated call to /v1/engines/list returned a 401 rather than a 404.
{
"text_prompts": [
{ "text": "a cast-iron kettle steaming on a wood stove, cold morning light", "weight": 1 },
{ "text": "blurry, low contrast", "weight": -1 }
],
"cfg_scale": 7,
"steps": 30,
"sampler": "K_DPMPP_2M",
"width": 1216,
"height": 832,
"samples": 1,
"seed": 1234
}
# v1 SDXL 1.0. This is the only Stability image surface with steps and sampler.
curl -f -sS -X POST \
"https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image" \
-H "Authorization: Bearer $STABILITY_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d @body.json > out.json
Local and open-weights tooling. This is where the parameter genuinely lives now, and where the rest of this page applies. Stability's own inference-only reference implementation for SD 3.5 takes steps on the command line:
# Stability's reference repo. Uses that model's published defaults.
python3 sd3_infer.py --prompt "a cast-iron kettle steaming on a wood stove" \
--model models/sd3.5_large.safetensors
# Override explicitly
python3 sd3_infer.py --prompt "…" --model models/sd3.5_large.safetensors \
--steps 40 --cfg 4.5 --sampler dpmpp_2m --shift 3.0
# Hugging Face diffusers. num_inference_steps defaults to 28 on the SD3 pipeline.
import torch
from diffusers import StableDiffusion3Pipeline
pipe = StableDiffusion3Pipeline.from_pretrained(
"stabilityai/stable-diffusion-3.5-large", torch_dtype=torch.bfloat16
).to("cuda")
image = pipe(
prompt="a cast-iron kettle steaming on a wood stove, cold morning light",
num_inference_steps=28,
guidance_scale=7.0,
).images[0]
Why do more steps stop helping?
Because sampling is a numerical solve, and steps are how finely you discretise it. The model defines a trajectory from pure noise to an image; the sampler approximates that trajectory in a finite number of hops. More hops means less discretisation error. Once that error drops below what your eye or your downstream use can detect, additional steps buy nothing except GPU time.
The honest version of the diminishing-returns story is that Stability publishes no quality-versus-steps curve for any image model, and no plateau point. What exists is a set of published defaults, plus one convergence figure from the sampler literature.
The defaults tell you where the people who trained the model chose to sit. Stability's reference script carries the reasoning in comments beside the constant:
# sd3_infer.py, Stability-AI/sd3.5
# Different models want different step counts but most will be good at 50, albeit that's slow to run
# sd3_medium is quite decent at 28 steps
STEPS = 40
Hugging Face's diffusers documents the tradeoff in one line on every pipeline: "More denoising steps usually lead to a higher quality image" at the expense of slower inference. Note "usually". Nobody in the primary sources claims monotonic improvement.
The convergence figure comes from the DPM-Solver++ paper, which reports that its solver "can generate high-quality samples within only 15 to 20 steps for guided sampling" and describes the older DDIM as "a first-order diffusion ODE solver that generally needs 100 to 250 steps for high-quality samples".
That range, 15 to 250, for the same model, is the actual answer to "how many steps do I need". It depends almost entirely on which solver you picked.
How does the sampler change the right step count?
The sampler is the ODE solver. The scheduler is the ladder of noise levels it walks. ComfyUI's KSampler offers 44 samplers and 9 schedulers, chosen independently.
Two mechanics break the intuition that steps equal compute.
Second-order samplers evaluate the model twice per step. This is visible in the source. sample_euler calls model(...) once inside its loop. sample_heun calls it once, then again on the corrector, on every step where the next sigma is non-zero:
# comfy/k_diffusion/sampling.py, sample_heun
denoised = model(x, sigma_hat * s_in, **extra_args)
d = to_d(x, sigma_hat, denoised)
dt = sigmas[i + 1] - sigma_hat
if sigmas[i + 1] == 0:
x = x + d * dt # Euler on the final step
else:
x_2 = x + d * dt
denoised_2 = model(x_2, sigmas[i + 1] * s_in, **extra_args) # second evaluation
d_2 = to_d(x_2, sigmas[i + 1], denoised_2)
x = x + (d + d_2) / 2 * dt
Twenty heun steps therefore cost roughly thirty-nine model evaluations, not twenty. Comparing "20 steps of euler" against "20 steps of heun" is comparing two workloads that differ by nearly 2x. Compare evaluations.
Some samplers quietly add a step. ComfyUI keeps a set called DISCARD_PENULTIMATE_SIGMA_SAMPLERS containing dpm_2, dpm_2_ancestral, uni_pc and uni_pc_bh2. For those, it increments the step count by one, computes the sigma ladder, then drops the second-to-last sigma. Ask for 20, get 21 scheduled.
Stability's own per-model config is the clearest illustration that step count and sampler are chosen together:
| Model | Steps | Sampler | CFG | Shift |
|---|---|---|---|---|
sd3_medium | 50 | dpmpp_2m | 5.0 | 1.0 |
sd3.5_medium | 50 | dpmpp_2m | 5.0 | 3.0 |
sd3.5_large | 40 | dpmpp_2m | 4.5 | 3.0 |
sd3.5_large_turbo | 4 | euler | 1.0 | 3.0 |
sd3.5_large_controlnet_* | 60 | euler | 3.5 | 3.0 |
Read that table as four different answers to "how many steps", all from the same vendor, all correct for their row.
How do steps interact with CFG scale?
They move together, and in the direction most people find counterintuitive: fewer steps wants less guidance, not more.
Stability's generate/sd3 schema documents cfg_scale on a 1 to 10 range and splits the default by model family. The Large and Medium models "use a default of 4". The Turbo and Flash models, the ones running four steps, "uses a default of 1". Their reference script agrees: 4.5 at 40 steps, 5.0 at 50, 1.0 at 4.
Two reasons. Classifier-free guidance is an extrapolation away from the unconditional prediction, and a long schedule has many small corrections to absorb it. On a four-step schedule the same push lands in a quarter of the moves, which is the fried, over-saturated look people blame on the model.
Guidance also destabilises high-order solvers. The DPM-Solver++ authors found that earlier ones "even become slower than DDIM when the guidance scale grows large", which is why their multistep variant exists at all. And it costs compute in its own right, since a guided evaluation runs both the conditional and unconditional predictions, so CFG and steps multiply into your bill rather than adding.
None of this is the same knob as temperature on a text model, despite constant confusion between them. If you came here from the language side, the mapping does not hold; see Temperature, Top-P, Top-K explained for what those actually control, and what you can and cannot make deterministic for the seed half of the question.
Why do Turbo and Flash models need only four steps?
Because the short schedule is the design point, not a compromise. These are distilled models: a fast student trained to reproduce in a handful of steps what the slow teacher does in dozens.
Stability's own Adversarial Diffusion Distillation paper introduces the method as one that "efficiently samples large-scale foundational image diffusion models in just 1-4 steps while maintaining high image quality", and reports that it "reaches the performance of state-of-the-art diffusion models (SDXL) in only four steps".
The product pages carry the same numbers. Stability describes SDXL Turbo as "utilizing Adversarial Diffusion Distillation to enable real-time image generation in as few as one step, while maintaining high-quality outputs." SD 3.5 Large Turbo generates images "in just 4 steps, making it considerably faster than Stable Diffusion 3.5 Large." SD 3.5 Flash uses "a 4 step process instead of 40".
That last phrase is the most useful sentence Stability publishes here, because it names a base figure at all: 40 steps undistilled against 4 distilled. It does not line up perfectly with their own reference script, which sets SD 3.5 Medium at 50 steps and SD 3.5 Large at 40, so treat the 40 as illustrative rather than as Medium's official default.
The audio side shows the identical pattern in schema form. stable-audio-2 accepts 30 to 100 steps and defaults to 50. stable-audio-2.5 accepts 4 to 8 and defaults to 8. The distilled model does not merely prefer fewer steps, it will not accept more.
# SD 3.5 Large Turbo, Stability's published config: 4 steps, cfg 1.0, euler.
python3 sd3_infer.py --prompt "a cast-iron kettle steaming on a wood stove" \
--model models/sd3.5_large_turbo.safetensors \
--steps 4 --cfg 1.0 --sampler euler
# SDXL Turbo in diffusers. One step, guidance switched off entirely.
from diffusers import AutoPipelineForText2Image
import torch
pipe = AutoPipelineForText2Image.from_pretrained(
"stabilityai/sdxl-turbo", torch_dtype=torch.float16, variant="fp16"
).to("cuda")
image = pipe(
prompt="a cast-iron kettle steaming on a wood stove",
num_inference_steps=1,
guidance_scale=0.0,
).images[0]
What do extra steps actually cost?
Roughly linear, and Stability publishes the arithmetic twice.
On the v1 image API the docs state that "When specifying 30 steps or fewer, generation costs 0.9 credits", and above that the cost is cost = 0.9 * (steps / 30). That is exactly proportional. Fifty steps costs 1.5 credits against 30 steps at 0.9.
On Stable Audio 2.0 the formula is credits = 17 + 0.06 * steps, with worked examples of "50 steps = 20 credits [default]" and "100 steps = 23 credits". A fixed component plus a linear term.
Locally the same linearity shows up as wall-clock time, since the model runs once per step, twice on a second-order sampler. Doubling steps roughly doubles GPU time for a change you may not see, which makes it the least efficient quality knob you have. Resolution, model choice and prompt all move the result further per unit of compute. The same logic governs Midjourney's quality parameter and speed modes, where the vendor publishes GPU-minute costs rather than step counts.
# Sweep steps against a fixed seed and sampler, then look at the grid.
for s in 4 8 12 16 20 28 40 60; do
python3 sd3_infer.py \
--prompt "a cast-iron kettle steaming on a wood stove, cold morning light" \
--model models/sd3.5_large.safetensors \
--sampler dpmpp_2m --cfg 4.5 --seed 1234 \
--steps "$s" --postfix "steps-$s"
done
What step counts should you actually use?
Start from the published default for your exact surface, change one variable at a time, and stop when a doubling stops showing a difference at 100% zoom. Every figure in this table is a vendor or maintainer default, not an opinion.
| Surface | Default steps | Range | Sampler | CFG |
|---|---|---|---|---|
Stability hosted image API (core, ultra, sd3) | not exposed | not exposed | not exposed | 4 base, 1 Turbo/Flash |
| Stability v1 REST, SDXL 1.0 | 30 | 10–50 | 10-value enum, auto if omitted | 7 (range 0–35) |
| SD 3.5 Large, Stability reference script | 40 | not stated | dpmpp_2m | 4.5 |
| SD 3.5 Medium, same script | 50 | not stated | dpmpp_2m | 5.0 |
| SD 3.5 Large Turbo, same script | 4 | not stated | euler | 1.0 |
| SD 3.5 Large ControlNets, same script | 60 | not stated | euler | 3.5 |
| diffusers SD3 pipeline | 28 | not stated | scheduler default | 7.0 |
| diffusers SDXL pipeline | 50 | not stated | scheduler default | 5.0 |
| diffusers SD 1.x / 2.x pipeline | 50 | not stated | scheduler default | 7.5 |
ComfyUI KSampler node | 20 | 1–10000 | euler, scheduler simple | 8.0 |
| Stable Audio 2.0 | 50 | 30–100 | not exposed | 7 |
| Stable Audio 2.5 and 3 | 8 | 4–8 | not exposed | 1 |
Anything more specific than that is community consensus and should be labelled as such. The widely repeated advice that SDXL-class models plateau somewhere around 20 to 30 steps on dpmpp_2m, and that going past 50 is wasted, matches the shape of these defaults and matches the DPM-Solver++ paper's 15 to 20 figure. It appears in no vendor documentation I could find. Treat it as a sensible starting point, not a fact, and verify it on your own model with the sweep above.
// ComfyUI KSampler defaults, from nodes.py. sampler_name and scheduler are
// combo widgets with no explicit default, so they land on the first entry
// of SAMPLER_NAMES and SCHEDULER_NAMES in comfy/samplers.py.
{
"seed": 0,
"steps": 20,
"cfg": 8.0,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1.0
}
// SD 3.5 Large ControlNets. steps, cfg, sampler and shift are Stability's
// own published values for the blur, canny and depth ControlNets.
{
"steps": 60,
"cfg": 3.5,
"sampler": "euler",
"shift": 3.0
}
# Same schedule, different step budgets, so you can compare like for like.
CONFIGS = {
"sd3.5_large": {"shift": 3.0, "steps": 40, "cfg": 4.5, "sampler": "dpmpp_2m"},
"sd3.5_medium": {"shift": 3.0, "steps": 50, "cfg": 5.0, "sampler": "dpmpp_2m"},
"sd3.5_large_turbo": {"shift": 3.0, "steps": 4, "cfg": 1.0, "sampler": "euler"},
}
What Stability does not publish
Writing the gaps down beats filling them with plausible numbers, which is what most pages on this keyword do.
- Any quality-versus-steps curve, for any image model. No plateau point, no comparison grid, no FID-against-steps chart in the product documentation.
- Any explanation for removing
stepsfrom the hosted image API. It is simply absent from every v2beta image schema, with no migration note attached. - Sampler or scheduler choice on v2beta. The v1 API had a ten-value
samplerenum. Nothing equivalent exists on the current endpoints. - A consistent story on SD 3.5 Flash. The
modelenum ongenerate/sd3lists exactly three values:sd3.5-large,sd3.5-large-turboandsd3.5-medium. The same endpoint's prose, its credit table and itscfg_scaleandstrengthnotes all describesd3.5-flash. Those two halves of one document disagree, and I could not resolve it without an API key. - SD 3.5 Flash on the Core Models list. The list dated May 20, 2026 does not include it, nor SDXL 1.0 base, nor SD 1.5. Models off that list are governed by their own individual licences, not the Community License.
Where the prompt fits, and where it does not
Steps is a sampler setting, not a prompt parameter, and no amount of prompt craft changes what it does. Writing "highly detailed, 50 steps" into a prompt sets nothing, in the same way that negative prompt support varies wildly by model and writing negations into a positive prompt does not create a negative one.
That cuts both ways. Prompt Architects builds the prompt. It does not generate the image, does not run your sampler, and will not pick a step count for you. If your renders are soft at 40 steps, more steps is almost never the fix; the CFG, the model or the description usually is.
What does transfer is discipline. Save the parameter block as a reusable template with model, sampler, steps and CFG as variables, so a model swap is a variable change rather than a rewrite. That is also what stops you carrying an SD 1.5-era habit of 50 steps and CFG 7 into a distilled model that wants four and one.
Every figure here was read from a primary source on August 27, 2026: the live OpenAPI document at api.stability.ai/v2alpha/openapi, the version 1 reference in the platform.stability.ai docs app, Stability's sd3.5 repository, the licence and Core Models pages on stability.ai, ComfyUI and diffusers source, and the two arXiv papers named above. Re-check them before trusting any step count, including these.
Stop rewriting prompts. Start shipping.
Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 5.0★ on the Chrome Web Store.
Create An Account