BlogComfyUI

ComfyUI workflows explained, node by node

How a ComfyUI workflow runs and what every node in a real FLUX graph does, with renders of each KSampler setting: seed, steps, CFG, sampler and denoise.

Esha Senior AI Developer
Updated 21 min readTested on ComfyUI 0.36.0 and 0.37.1

On this page18 sections

The short version

  • A workflow is a graph. Each node does one job, and what it outputs becomes the next node's input.
  • ComfyUI works out what to run starting from the output nodes, and on the next run it skips anything whose inputs haven't changed.
  • Until VAE Decode, there's no picture at all. Everything before it happens in a compressed space called a latent.
  • The seed picks the starting noise. Keep it, and every other setting, and you get the same image back.
  • A workflow file is plain JSON, and ComfyUI hides a copy of it inside every PNG and MP4 it saves.

The first time you open ComfyUI you get a canvas full of boxes and coloured wires, and it's fair to think someone has made image generation harder than it needs to be. Give it ten minutes and it flips around. The boxes aren't the complicated part. They're the steps every image generator runs, laid out where you can see them and change them. A prompt box does all the same things. It just doesn't let you touch any of them.

This guide goes through one real workflow in the order the data moves through it. It's the same file I use in the video, and you can download it with a note beside every node and follow along in your own install.

What a workflow is

A ComfyUI workflow is a directed graph, and it's made of three things:

  • Nodes. One box, one job: load a model, turn text into numbers, sample, decode, save.
  • Links. The wires. Each one runs from an output socket on one node to an input socket on another.
  • Types. Every socket carries one kind of data, and ComfyUI gives each kind its own colour.

The types do more work than they seem to. You can't plug a MODEL output into a CLIP input, because the editor won't let the wire connect. Once you know the six colours below, you can read a workflow you've never seen before, in the same way you can follow a wiring diagram without knowing what the machine does.

MODEL: the image model CLIP: the text encoder CONDITIONING: your prompt, encoded LATENT: the image in compressed form VAE: the decoder IMAGE: pixels you can see

How ComfyUI decides what to run

This surprises people coming from simpler tools. When you press Run, ComfyUI doesn't start at the top-left box. It starts from the output nodes, such as Save Image, Save Video or Preview Image, and works backwards through everything they depend on. A node that doesn't lead to an output is never run.

It also remembers results. Run the graph again after changing only the seed, and the loaders don't reload twelve gigabytes from disk. ComfyUI reuses their output and re-runs only the nodes your change affects. That's why the first image of a session takes a while and the next one is quick, and why changing the seed is cheap but switching models isn't.

Worth knowing If a node you added seems to do nothing, check that its output eventually reaches a Save Image or Preview Image. If it doesn't, ComfyUI has no reason to run it.

The workflow we're going to read

Here's the whole graph: text to image with FLUX.1 Krea [dev], nine working nodes, each with a Note beside it. Every value you can see is the value the file ships with.

The complete FLUX.1 Krea text-to-image workflow: Load Diffusion Model, Load CLIP (Dual), CLIP Text Encode, EmptySD3LatentImage, Conditioning Zero Out, KSampler, Load VAE, VAE Decode and Save Image, each with a coloured Note explaining it.
The full workflow, drawn from its own JSON file. Each node shares its colour with the Note that explains it. You set those colours yourself in ComfyUI (right-click a node, then Colors), and it makes a graph much easier to hand to someone else.

You can also open the same file right here. Drag to move around, click into it and scroll to zoom, and click a node to read its note:

image-workflow-flux-krea.json Loading…
Click any node to read its note

Node 1: Load Diffusion Model

The first node loads the model that makes the image. Its internal name is UNETLoader, ComfyUI shows it as Load Diffusion Model, and it has one output: MODEL.

The Load Diffusion Model node with unet_name set to flux1-krea-dev_fp8_scaled.safetensors and weight_dtype set to default, beside its note.
One file in, one MODEL out.

Click the unet_name value and you get a list of every diffusion model you have. That list is simply the contents of one folder:

Where the list comes from
ComfyUI/models/diffusion_models/flux1-krea-dev_fp8_scaled.safetensors

Put a .safetensors file in there, press R (or refresh the browser tab), and it shows up in the dropdown. There's no install step.

The second setting, weight_dtype, lets you load a 16-bit model as 8-bit to roughly halve the memory it needs. This file is already FP8, so leave it on default.

Node 2: Load CLIP (Dual)

A diffusion model can't read. It works with numbers, so something has to turn your sentence into numbers it can use. That's the job of the text encoders, and this node loads them.

The Load CLIP (Dual) node with clip_name1 clip_l.safetensors, clip_name2 t5xxl_fp16.safetensors, type flux and device default.
FLUX uses two text encoders, so it needs the dual loader. The type setting tells ComfyUI which model family they're for.

FLUX reads your prompt with two encoders at once. CLIP-L is small and was trained on short image captions. T5-XXL is a full language model that reads long, grammatical sentences. Having T5 is a big part of why FLUX follows a written description instead of wanting a list of comma-separated tags.

What goes in: the two files you pick. What comes out: a CLIP, which is a text reader that's loaded and ready but hasn't read anything yet.

Two nodes that sound the same Load CLIP loads the thing that understands text. CLIP Text Encode uses it on the words you typed. One is the dictionary; the other is looking something up in it.

Node 3: CLIP Text Encode

This is where your prompt enters the graph. It takes the CLIP from the previous node plus whatever you typed, and outputs CONDITIONING: your prompt as numbers the model can be steered by.

The CLIP Text Encode node with a long photorealistic portrait prompt in its text box and a scrollbar, and a CONDITIONING output.
The prompt box is an ordinary text area, which is why it has a scrollbar. The prompt in this file is 213 words in four paragraphs; FLUX rewards that kind of detail.

Two things about prompting FLUX that you can see in that node:

  • Write sentences. "Standing beside a large sunlit window in a quiet contemporary apartment" gives the model far more to work with than "window, sunlit, apartment, quiet".
  • Describe the light and the camera. Most of this prompt is about where the sun is coming from and how the shadows fall. That's what makes the result look like a photograph rather than a render.

Node 4: Conditioning Zero Out

KSampler has two prompt inputs, positive and negative. In most Stable Diffusion workflows the negative one gets a second prompt describing what you don't want. This workflow does something different with it.

The Conditioning Zero Out node taking a conditioning input and producing a neutral CONDITIONING output, with its note.
The node most tutorials skip. It gives KSampler something valid for an input that, at CFG 1.0, doesn't affect the result.

FLUX.1 [dev] is guidance-distilled. A negative prompt normally works through classifier-free guidance, where the sampler compares a run with your prompt against a run with the negative one. FLUX dev had the effect of that comparison trained into it, so it runs at cfg 1.0, and at 1.0 the negative input isn't used at all.

KSampler still needs something plugged in, though. So the workflow takes the encoded prompt, passes it through Conditioning Zero Out to empty it, and connects that to the negative input. Your real prompt goes to positive, and the negative side is deliberately blank.

Don't copy this onto SDXL On a model that isn't distilled, running at a CFG of 5 to 8, zeroing the negative throws away a real control. There you want a second CLIP Text Encode with an actual negative prompt in it.

Node 5: EmptySD3LatentImage

Before the model can paint, it needs a canvas, and the canvas isn't an image. It's a latent: a small grid of numbers that the model works in.

The EmptySD3LatentImage node with width 1024, height 1024 and batch_size 1, beside its note.
Width, height and batch size. Everything after this node inherits the shape you set here.

A 1024×1024 image isn't handled as a million pixels while it's being made. FLUX's VAE compresses eight times in each direction, so the model actually works on a 128×128 grid with 16 numbers at each position. That grid is the latent. Working that small is what makes generation fast enough to be practical, and it's why there's nothing you could look at until the decode step at the end.

  • width and height set the final image size. The node moves in steps of 16, and FLUX does its best work at around a million pixels in total, such as 1024 × 1024 or 832 × 1248.
  • batch_size is how many images to make in one run. Each one costs memory, so four at 1024×1024 is a real jump from one.
Why "SD3" in a FLUX workflow? FLUX and Stable Diffusion 3 use the same shape of latent (16 channels), so ComfyUI reuses one node for both. The older Empty Latent Image makes a 4-channel latent for SD 1.5 and SDXL. If you use that one here, it still works: KSampler notices the empty latent doesn't match the model and reshapes it. The SD3 node is simply the one that's the right shape to begin with.

Node 6: KSampler and its settings

This is the node that makes the image. Everything before it was preparation: a model, an encoded prompt, an empty negative and an empty latent. KSampler takes all four and does the work.

The KSampler node with seed 526019168208450, control after generate randomize, steps 20, cfg 1.0, sampler_name euler, scheduler simple and denoise 1.00, beside a long explanatory note.
Four inputs, one LATENT output, and seven settings that decide the result.

In one sentence: it fills the latent with random noise, then removes that noise a step at a time, steering each step with your prompt, until an image has formed. That's diffusion. The core idea really is that simple.

Seed

The seed decides what the starting noise looks like. Keep the seed and every other setting the same, and you get the same image back. Change only the seed and the same prompt gives you a different picture.

Render with seed 11: a woman with one arm raised, in a cream jumper and wide jeans, beside a palm. Render with seed 22: the same pose and outfit, a different woman, a different room. Render with seed 33: the same prompt again, with a monstera plant and a new face. Render with seed 44: the same arm pose with a wider stance, a different face and a grassy plant. seed 11
seed
One prompt, four seeds, nothing else changed. The prompt describes the pose in detail, so the raised arm and the hand on the hip survive in all four. The face, the room, the plant and even the stance come from the noise.

"The same image" has one small print. I re-ran this guide's portrait nine days after making it, after a ComfyUI update, with the same seed and settings. It was the same picture to the eye, but not bit for bit: pixels had moved by 1.7 levels out of 255 on average. A new version of ComfyUI, PyTorch or your graphics driver can shift the maths that slightly. On one setup that stays the same, a seed gives you exactly the same image.

The setting under it, control after generate, decides what happens to the seed after each run. randomize picks a new one, so every click gives you something new. The moment you get an image you like, switch it to fixed. Otherwise the next run replaces the seed and you can't get that picture back.

Steps

How many times the model refines the image on its way from noise to picture. More isn't automatically better. It's slower, and past a certain point the picture has already formed.

The portrait at 4 steps: blurry and washed out. The portrait at 8 steps: the face formed but soft. The portrait at 12 steps: sharper, freckles appearing. The portrait at 20 steps: sharp and detailed. The portrait at 30 steps: nearly identical to 20. The portrait at 50 steps: similar framing but a noticeably different face. steps 20
steps
Same prompt, same seed (429741262831993), same sampler. Only the step count changes.

Every model has a range where it does its best work. FLUX dev is comfortable around 20 to 30. Fast distilled models like Z-Image Turbo are built for about 8. Going far past a model's range doesn't buy you quality. As the 50-step render shows, it mostly buys you a slightly different picture and a longer wait.

CFG

Classifier-free guidance: how hard each step is pushed toward your prompt. Higher values follow the prompt more literally and can start to look overcooked. Lower values give the model more freedom and can drift away from what you asked for.

In this workflow it's 1.0, and that's deliberate. It's the distillation explained under Conditioning Zero Out. On SDXL or SD 1.5 you'd usually be somewhere between 5 and 8.

Sampler and scheduler

These two get mixed up constantly, so here's the difference in one line each:

The sampler decides how noise is removed at each step.
The scheduler decides how much noise each step removes.

euler, dpmpp_2m, uni_pc and res_multistep are different methods of getting from noise to an image, and they land in slightly different places:

The portrait with the euler sampler. The portrait with the dpmpp_2m sampler: the same woman and framing, with small changes to the earring, the necklace and the plant. The portrait with the uni_pc sampler: the same woman and framing, with a different earring, a lower necklace pendant and a plant in a glass vase. The portrait with the res_multistep sampler: the same woman and framing, with small changes to the earring, the necklace and the plant. euler
sampler_name
Same seed, 20 steps, simple scheduler, four samplers. Flick between them and watch the earring, the necklace and the plant behind her: the face and the light barely move. Switching sampler changed about as much of this picture as going from 20 to 30 steps did.

So the sampler is a fine-tuning control, not a quality one. The scheduler (simple, normal, karras, beta and others) spreads those steps across the journey from noise to image. Some take big steps early, others save more of the steps for the fine detail at the end. Unless you're chasing a particular look, leave both on whatever the workflow came with. They were picked to suit the model.

Denoise

How much of the journey from noise to image to actually do. At 1.0 the model starts from pure noise and builds the whole picture, which is what you want for text-to-image, and why it's 1.0 here.

Denoise becomes the most important setting on the node the moment you give it an existing image instead of an empty latent. At 0.5 the model only partly re-noises your picture, so the layout survives and the look changes. At 0.9 there's hardly anything of the original left. Image-to-image, inpainting and a lot of upscaling workflows all come down to this one number.

If you want the same image again You need the seed and every other setting unchanged. Change anything upstream, whether it's a word in the prompt, the size or the sampler, and the same seed gives you a different picture.

Node 7: Load VAE

KSampler's output is still a latent. To turn it into pixels you need the other half of the compression: the VAE, short for variational autoencoder. This node loads it.

The Load VAE node with vae_name set to ae.safetensors, beside its note.
One dropdown, listing the files in ComfyUI/models/vae/.

Some models come as a single all-in-one checkpoint with the VAE inside, and then Load Checkpoint gives you one and this node isn't needed. FLUX keeps its parts separate, so the VAE is a file you download and pick yourself: ae.safetensors, 335 MB.

Node 8: VAE Decode

The translation step. It takes the finished latent from KSampler and the VAE you loaded, and outputs an IMAGE. This is the first point in the whole workflow where real pixels exist.

The VAE Decode node with samples and vae inputs and an IMAGE output, beside its note.
Two inputs, one output, no settings.

If a decoded image comes out with an odd colour cast, a faint grid pattern or flat, washed-out contrast, the usual cause is a VAE made for a different model family. They aren't interchangeable.

Node 9: Save Image

The last node writes the result into ComfyUI/output/ and shows it on the canvas.

The Save Image node with filename_prefix flux_krea, showing the generated portrait of a woman beside a sunlit window, with its note.
The picture this graph made. filename_prefix is the start of the saved file's name.

filename_prefix can include folders, so clients/acme/hero saves to output/clients/acme/hero_00001_.png. It's an easy way to keep projects apart without moving files by hand.

Save Image also does something quietly useful: it writes the entire workflow into the PNG. More on that below.

Reading the graph as three paths

Once you've seen the nodes one at a time, the whole graph gets simpler. There are only three routes through it.

The full workflow with Load CLIP, CLIP Text Encode and KSampler highlighted, showing the path a prompt takes.
The text path: Load CLIP, CLIP Text Encode, KSampler. Words become numbers, and the numbers steer the sampler.
The full workflow with EmptySD3LatentImage, KSampler, VAE Decode and Save Image highlighted, showing the path the image takes.
The image path: empty latent, KSampler, VAE Decode, Save Image. A blank canvas becomes noise, the noise becomes a picture.

The third is the model path: Load Diffusion Model straight into KSampler. It's a single wire, but it's where add-ons that change the model plug in, which is the subject of What is a LoRA?

How workflow files work, and where they're saved

A workflow is a JSON file. There are two different kinds of JSON, though, and knowing which is which saves a lot of confusion.

Workflow formatAPI format
What's in itNodes, positions, sizes, colours, groups, notes and linksOnly the nodes, their values and how they connect
How you get itWorkflow → Export, or saving normallyWorkflow → Export (API)
What it's forOpening, editing and sharing with peopleSending to ComfyUI's /prompt endpoint from code

The files on this site are the workflow format, because they're meant to be opened, read and changed. If you're driving ComfyUI from Python, export the API version: same graph, none of the layout.

Where ComfyUI saves your workflows

Save a workflow with Ctrl + S (or Workflow → Save) and it's written as a .json file to ComfyUI/user/default/workflows. Everything in that folder is listed in the Workflows panel in the sidebar, ready to open again. In the Desktop app the folder sits inside the install:

Saved workflows, Desktop app
%LOCALAPPDATA%\Comfy-Desktop\ComfyUI-Installs\ComfyUI\ComfyUI\user\default\workflows

The first ComfyUI in that path is the install's name, so yours may differ. Images and videos don't go here: Save Image and Save Video write to ComfyUI/output.

The workflow hidden in your images

This is the most useful thing ComfyUI does that people don't know about. When Save Image writes a PNG, it tucks two pieces of text into the file: workflow (the full graph) and prompt (the API version). The picture is the project file.

Drag any PNG that ComfyUI made back onto the canvas and the whole workflow rebuilds itself, every node and every value, seed included. That works for images other people made too, which is mostly how workflows get passed around.

Video works the same way. Save Video writes the workflow into the MP4, and you can read it out without opening ComfyUI at all:

Read the workflow out of an MP4
ffprobe -v quiet -show_entries format_tags=workflow -of default=nw=1 ComfyUI_00033_.mp4
What strips it out Most social platforms re-encode what you upload and throw the metadata away. So does editing the picture in a lot of image editors. If a workflow matters, keep the original file or export the JSON.

Living with workflows day to day

Start from a template

ComfyUI ships working workflows for most of the models it supports. Open the Templates panel (or Workflow → Browse Templates) and you get image, video, audio and 3D categories, each template already wired correctly for its model. It's a far better starting point than a random JSON file from a forum.

The ComfyUI template browser on the Image category: Z-Image-Turbo text to image, Z-Image-Turbo Int8, Krea-2, Nano Banana Pro, Nano Banana 2 image edit, Qwen Image Edit 2509 and 2511, and FireRed Image Edit 1.1.
The built-in template browser. Each one is a complete, working workflow for the model it names.

When a workflow won't run

Two problems cause nearly all of these, and ComfyUI tells you which one you've got.

Missing models. The graph is fine but a file it needs isn't on your disk. The node gets a red outline and an error message pops up:

ComfyUI error message reading 2 errors found, resolve them before running the workflow, with a View details button.
Click View details to see the name of the file it can't find.

Most templates go a step further and offer to download what's missing, with the sizes listed:

The Missing Models panel listing ae.safetensors, qwen_3_4b.safetensors and z_image_turbo_bf16.safetensors with Download buttons and a Download all 19.27 GB button.
19.27 GB is a normal number here. Check it before you click, not after.

Missing nodes. The workflow uses a custom node pack you haven't installed. Open the Manager, choose Missing Nodes, install what it lists and restart. (A custom node is a small Python file, and you can write one yourself.)

The ComfyUI Nodes Manager showing node packs with install buttons and a sidebar containing All Extensions, Not Installed, All Installed, Updates Available, Conflicting and Missing Nodes.
The sidebar is the useful part. Missing Nodes reads the workflow you have open and lists exactly what it needs.

No Manager button at all? Then your install doesn't have it switched on. The install guide shows how for each kind of install.

Mute and bypass

Two shortcuts worth learning on your first day, because they let you try ideas without deleting anything:

  • Ctrl + M mutes a node. It's left out of the run completely, so any node that needs its output can't run either, and ComfyUI tells you an input is missing.
  • Ctrl + B bypasses a node. It's skipped, but whatever came in is passed straight out, so the rest of the graph keeps working.

That difference is the point. Bypass a LoRA to see the image without it. Mute a second Save Image you only need now and then. Press the same keys again to switch them back on.

Five mistakes that cost beginners an afternoon

  1. Leaving the seed on randomize after finding a good image. Switch to fixed straight away, then change one thing at a time.
  2. Adding steps to fix a bad image. Steps fix detail that hasn't finished forming. They don't fix a weak prompt, the wrong model or an unlucky seed.
  3. Using a VAE from a different model family. Washed-out or tinted results almost always mean this.
  4. Running a distilled model at high CFG. FLUX dev and the Turbo-style models want a CFG around 1.0. Raising it burns the image.
  5. Deleting a node to see the result without it. Bypass it with Ctrl + B instead. You get the same comparison, and one more press puts it back with its settings intact.

Quick reference

Node
One step in the graph, drawn as a box. It takes inputs, does one job and produces outputs.
Link
A wire from one node's output to another node's input. Its colour shows the type of data it carries.
Latent
The compressed form the model works in. For FLUX at 1024×1024 it's a 128×128 grid with 16 channels.
Conditioning
Your prompt after the text encoder has turned it into numbers.
VAE
The model that converts between pixels and latents. VAE Decode turns the finished latent into an image.
Seed
The number that decides the starting noise. Same seed and same settings give the same image.
Steps
How many times the sampler refines the image. FLUX dev works well at 20 to 30.
CFG
How strongly each step follows the prompt. 1.0 for distilled models like FLUX dev, 5 to 8 for SDXL.
Sampler
The method used to remove noise at each step, such as euler or dpmpp_2m.
Scheduler
How the noise removal is spread across the steps, such as simple or karras.
Denoise
How much of the image is regenerated. 1.0 for text-to-image, lower to keep part of an input image.

Where to go next

You now have the vocabulary for nearly every image workflow you'll come across: loaders, prompt encoding, a latent, a sampler, a decode and a save. Video workflows are the same skeleton with a frame count added. The WAN 2.2 workflow swaps the empty latent for a node that also asks for a length, and Save Image for Create Video and Save Video. Everything in between you already know.

Three guides build on this one:

If ComfyUI isn't installed yet, or your install has no Manager, start with the install guide.

Questions people ask

What is a ComfyUI workflow?

A ComfyUI workflow is a node graph saved as a JSON file. Each node does one step, such as loading a model, encoding a prompt, sampling, decoding or saving, and links carry data from one node's output to the next node's input. Running the workflow executes those steps in dependency order and produces an image, a video or another output.

What is a latent image in ComfyUI?

A latent is the compressed form the model generates in. For a 1024×1024 FLUX image it's a 128×128 grid with 16 channels, eight times smaller in each direction than the final picture. The model works entirely in this space, and the VAE Decode node converts the result into visible pixels at the end.

What is the difference between a sampler and a scheduler?

The sampler is the method that removes noise at each step (euler, dpmpp_2m, uni_pc and so on). The scheduler decides how much noise each step removes across the run. Both change the final image slightly, and both are usually best left at whatever the workflow was built with.

How many steps should I use in ComfyUI?

It depends on the model. FLUX.1 dev works well at 20 to 30 steps, while distilled and Turbo models are designed for around 8. Going far beyond a model's range mostly costs time and can change the image rather than improve it. Test with a fixed seed at a few step counts and use the lowest one that looks right.

Why is CFG set to 1.0 in FLUX workflows?

FLUX.1 [dev] is guidance-distilled: the effect of classifier-free guidance was trained into the model, so it doesn't need a separate negative pass when generating. At CFG 1.0 the negative input isn't used, which is why these workflows connect a zeroed-out conditioning to it instead of a real negative prompt. Raising CFG on FLUX dev usually makes the image worse.

Where does ComfyUI save workflows?

In ComfyUI/user/default/workflows, as .json files, whenever you save with Ctrl+S or Workflow → Save. In ComfyUI Desktop on Windows that folder is inside the install, at %LOCALAPPDATA%\Comfy-Desktop\ComfyUI-Installs\ComfyUI\ComfyUI\user\default\workflows for an install named ComfyUI. The images and videos a workflow makes go to ComfyUI/output instead.

How do I load a workflow in ComfyUI?

Drag the .json file onto the canvas, or a PNG or MP4 that ComfyUI made, since those carry their workflow inside them. You can also use Workflow → Open (Ctrl+O), or pick a saved one from the Workflows panel in the sidebar. If nodes turn red after it loads, the workflow needs models or custom nodes you don't have yet.

Can I open a ComfyUI workflow from a generated image?

Yes. ComfyUI writes the full workflow into every PNG it saves, and into MP4 files saved with Save Video. Drag the file onto the ComfyUI canvas and the whole graph rebuilds, including the seed. Re-encoding the file, for example by uploading it to most social platforms, removes that information.

What is the difference between mute and bypass?

Mute (Ctrl+M) leaves a node out of the run completely, so any node that needs its output can't run either. Bypass (Ctrl+B) skips the node but passes its input straight through, so the rest of the graph keeps running. Bypass is the one to use when you want to take something like a LoRA out of a chain for a moment; mute suits an extra Save Image you only need now and then.

Do I need ComfyUI Manager to use workflows?

Not for workflows that only use built-in nodes, which includes every official template. You need it once a workflow depends on a custom node pack: the Manager's Missing Nodes view reads the open workflow, lists what it needs and installs it. ComfyUI Desktop has the Manager on by default; portable and manual installs need it switched on.