ComfyUI has become the most powerful node-based interface for running diffusion models locally, with the upstream comfyanonymous/ComfyUI repository crossing roughly 114,000 GitHub stars by May 2026 and the project shipping a new core release roughly every two weeks. This ComfyUI tutorial walks you through 13 practical steps that take you from a clean machine to a production-grade workflow generating SDXL, Stable Diffusion 3.5 Large, and FLUX.1 [dev] images, with LoRA, ControlNet, image-to-image, and an API server bolted on top.
By the end of this guide you will have a working ComfyUI v0.22.0 installation, a reproducible conda or venv environment, three downloadable workflow JSON files, a custom node bundle managed by ComfyUI Manager, and a small Python client that drives the ComfyUI HTTP API from outside the browser. Every command, file path, and configuration value has been tested against ComfyUI v0.22.0 (released May 20, 2026) on Python 3.12 with PyTorch 2.7, the combination that the upstream changelog currently recommends for new installs.
Don't miss new tech stories on Google
Add Tech Insider once in the Google app and our stories appear in your news suggestions.
Why a ComfyUI Tutorial Still Matters in 2026
Diffusion tooling in 2026 splits roughly into three camps. The first is hosted UIs like Midjourney and the OpenAI image API, where you trade control for convenience. The second is “single-page” local UIs such as Automatic1111’s web UI and Forge, which expose a fixed pipeline through tabs and dropdowns. The third is ComfyUI, a node-based DAG editor where every step of a diffusion pipeline – checkpoint loading, prompt encoding, sampling, VAE decoding, post-processing – is an explicit, swappable node.
The reason this matters: every new model architecture that appears in 2025 and 2026, from FLUX.1 to Stable Diffusion 3.5 to Wan-style video models, ships its reference workflow as a ComfyUI graph rather than a one-click button. The Black Forest Labs FLUX.1 [dev] model card on Hugging Face publishes a ComfyUI workflow as the canonical way to run the model, and the same is true for Stability AI’s Stable Diffusion 3.5 Large. If you want to run new models on day one, this ComfyUI tutorial is the most direct path.
The financial backing is also catching up to the open-source momentum. ComfyUI’s commercial entity raised a $30 million round at a roughly $500 million valuation led by Craft Ventures in 2026, a deal we covered in our ComfyUI funding analysis. That capital is paying for the ComfyUI Desktop app, the workflow registry, and the rapid bi-weekly release cadence you are about to install.
Prerequisites and Hardware Sizing
Before you start this ComfyUI tutorial, confirm that your machine meets the realistic minimums. ComfyUI itself is light – it is the diffusion models that hurt. SDXL needs at least 8 GB of VRAM to be comfortable; FLUX.1 [dev] in fp8 needs at least 12 GB; Stable Diffusion 3.5 Large in fp8 needs at least 12 GB; in bf16 you want 16 GB or more. CPU-only inference works, but a single SDXL image at 1024×1024 can take more than 5 minutes on a desktop CPU, which is not a workflow you want to iterate on.

| Component | Minimum | Recommended | Notes |
|---|---|---|---|
| Python | 3.10 | 3.12 | 3.13 works on many nodes but breaks a few custom packages |
| PyTorch | 2.5 | 2.7 | Use the CUDA 12.4 wheels for RTX 40/50 series |
| GPU VRAM | 6 GB (SD 1.5 only) | 16 GB (FLUX, SD 3.5) | RTX 4090 24 GB is the comfortable default |
| System RAM | 16 GB | 32 GB | FLUX text encoder offload uses CPU RAM |
| Disk | 50 GB free | 200 GB free SSD | One FLUX + one SD 3.5 + LoRAs fills 60 GB fast |
| OS | Windows 10, Ubuntu 22.04, macOS 14 | Ubuntu 24.04 or Windows 11 | Apple Silicon works via MPS but is slower |
| ComfyUI | v0.19.x | v0.22.0 | Bi-weekly releases; pin a version for reproducibility |
Two more practical notes. First, GPU rental prices for the high-end Blackwell cards have surged in 2026, as documented in our Blackwell GPU rental price analysis, so doing initial development on a local RTX 4080 16 GB or RTX 4090 24 GB tends to pay back quickly compared to renting an H100 per hour. Second, the Python install matters more than people expect – pyenv on Linux/macOS and the python.org installer on Windows are the safest defaults; the Microsoft Store Python and Anaconda’s base environment both cause path issues with PyTorch wheels.
Step 1: Install Python 3.12, Git, and a Clean Virtual Environment
The first job is to give ComfyUI an isolated Python environment that you control. Do not install it into your system Python. On Ubuntu 24.04, the following commands give you a clean base.
# Ubuntu 24.04 / Debian 12
sudo apt update
sudo apt install -y python3.12 python3.12-venv python3.12-dev
git build-essential ffmpeg curl
# Sanity check
python3.12 --version # expect: Python 3.12.x
git --version # expect: git version 2.43.x or newer
# Project directory
mkdir -p ~/ai/comfy
cd ~/ai/comfy
# Isolated virtual environment
python3.12 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip wheel setuptools
On Windows, install Python 3.12 from python.org with “Add to PATH” ticked, then run the same python -m venv .venv and activate it with .venvScriptsactivate. On macOS, use brew install [email protected] git ffmpeg and the rest of the commands are identical. The most common ComfyUI tutorial failure happens here, with users accidentally using Python 3.13 or the system 3.10, which then breaks a third of the custom nodes you will install later.
Step 2: Install PyTorch 2.7 with the Right CUDA Wheel
ComfyUI’s requirements file leaves PyTorch unpinned because the right wheel depends on your GPU. Install PyTorch first with the matching CUDA index URL, then let ComfyUI’s requirements pick up everything else. The official PyTorch installer matrix is the source of truth, but for RTX 40-series and RTX 50-series Blackwell cards the CUDA 12.4 wheels are the safe choice in May 2026.
# Inside the activated .venv
# NVIDIA RTX 30/40/50 series, Linux + Windows
pip install --upgrade torch==2.7.0 torchvision==0.22.0
--index-url https://download.pytorch.org/whl/cu124
# Apple Silicon (M1/M2/M3/M4)
# pip install --upgrade torch==2.7.0 torchvision==0.22.0
# AMD ROCm 6.2 on Linux
# pip install --upgrade torch==2.7.0 torchvision==0.22.0
# --index-url https://download.pytorch.org/whl/rocm6.2
# Verify CUDA visibility
python - <<'PY'
import torch
print("torch:", torch.__version__)
print("cuda available:", torch.cuda.is_available())
print("device:", torch.cuda.get_device_name(0) if torch.cuda.is_available() else "cpu")
print("bf16 supported:", torch.cuda.is_bf16_supported() if torch.cuda.is_available() else False)
PY
If torch.cuda.is_available() prints False on a machine with an NVIDIA GPU, you almost always have one of three problems: an old driver (need 555 or newer for CUDA 12.4 wheels), a mismatched CUDA toolkit installed alongside the wheel, or you forgot to activate the virtual environment. Fix the driver before fighting ComfyUI.
Step 3: Clone ComfyUI v0.22.0 and Install Requirements
Now bring in ComfyUI itself. Pin to a tagged release rather than tracking master; the project ships every two weeks and breaking changes are not unheard of. v0.22.0, released May 20, 2026, is the version this ComfyUI tutorial is built and tested against.
cd ~/ai/comfy
git clone https://github.com/comfyanonymous/ComfyUI.git
cd ComfyUI
# Pin to a known-good release tag
git checkout v0.22.0
# Install ComfyUI's own dependencies
pip install -r requirements.txt
# Smoke-launch on CPU first to confirm imports load
python main.py --cpu --listen 127.0.0.1 --port 8188 &
COMFY_PID=$!
sleep 8
curl -s http://127.0.0.1:8188/system_stats | head -c 400
echo
kill $COMFY_PID
A successful smoke test prints a JSON object containing system, devices, and a vram_total field. If you instead see an ImportError for torchvision or safetensors, that almost always means Step 2 installed the wrong PyTorch index URL and pip then downgraded torchvision when Step 3 ran. Reinstall torch and torchvision with the explicit --index-url flag and retry.
Step 4: Install ComfyUI Manager and Configure Model Paths
ComfyUI Manager is not optional. It is the package manager that handles custom nodes, missing-node detection when you open a downloaded workflow, model downloads, and version pinning. Install it as a custom node first, before you do anything else with workflows.

cd ~/ai/comfy/ComfyUI/custom_nodes
git clone https://github.com/ltdrdata/ComfyUI-Manager.git
cd ComfyUI-Manager
pip install -r requirements.txt
# Optional but recommended: pin Manager to a release tag too
git fetch --tags
git checkout $(git tag | grep -E '^[0-9]+.' | sort -V | tail -1)
cd ~/ai/comfy/ComfyUI
ls -1 models/ # checkpoints, clip, controlnet, loras, vae, etc.
If you already keep models on a separate drive – for example a 4 TB NVMe used by both Automatic1111 and ComfyUI – do not copy them. Edit the extra_model_paths.yaml file at the repo root instead, which lets multiple front-ends share one model library.
# ~/ai/comfy/ComfyUI/extra_model_paths.yaml
shared_library:
base_path: /mnt/models
checkpoints: SD/checkpoints/
clip: SD/clip/
clip_vision: SD/clip_vision/
controlnet: SD/controlnet/
loras: SD/loras/
upscale_models: SD/upscale_models/
vae: SD/vae/
unet: SD/unet/
diffusers: SD/diffusers/
embeddings: SD/embeddings/
Step 5: Download the Core Model Stack (SDXL, SD 3.5, FLUX.1)
This is the step that takes the longest in wall-clock time and the most discipline in disk planning. Three model families cover roughly 95 percent of real workflows in 2026: SDXL for fast iteration, Stable Diffusion 3.5 Large for high-fidelity photorealism, and FLUX.1 [dev] for state-of-the-art prompt adherence. The huggingface-cli tool authenticates once and then resumes correctly on flaky networks.
pip install --upgrade "huggingface_hub[cli]"
huggingface-cli login # paste your HF read token
cd ~/ai/comfy/ComfyUI/models
# 1. SDXL base 1.0 (good for fast iteration, ~6.9 GB)
huggingface-cli download stabilityai/stable-diffusion-xl-base-1.0
sd_xl_base_1.0.safetensors
--local-dir checkpoints --local-dir-use-symlinks False
# 2. Stable Diffusion 3.5 Large (gated, accept the license first)
huggingface-cli download stabilityai/stable-diffusion-3.5-large
sd3.5_large.safetensors
--local-dir checkpoints --local-dir-use-symlinks False
# 3. FLUX.1 [dev] (gated, accept the license first)
huggingface-cli download black-forest-labs/FLUX.1-dev
flux1-dev.safetensors ae.safetensors
--local-dir unet --local-dir-use-symlinks False
# 4. Text encoders for FLUX and SD 3.5
huggingface-cli download comfyanonymous/flux_text_encoders
t5xxl_fp8_e4m3fn.safetensors clip_l.safetensors
--local-dir clip --local-dir-use-symlinks False
Two pitfalls deserve a warning. First, FLUX.1 [dev] and Stable Diffusion 3.5 Large are gated repositories, which means you must visit each model card on Hugging Face, accept the license, and only then will huggingface-cli download succeed with a 200 instead of a 401. Second, the fp8 text encoder weights cut roughly 9 GB off VRAM usage on FLUX with no measurable quality loss in side-by-side comparisons, which is why every modern ComfyUI tutorial defaults to t5xxl_fp8_e4m3fn.safetensors on consumer GPUs.
Step 6: First Launch and the Default txt2img Workflow
Launch ComfyUI in normal mode and open the web UI. The default workflow that appears in v0.22.0 is a text-to-image graph that uses the first checkpoint in models/checkpoints. Pick sd_xl_base_1.0.safetensors in the Load Checkpoint node, type a prompt, and queue the first generation.
cd ~/ai/comfy/ComfyUI
python main.py
--listen 0.0.0.0
--port 8188
--preview-method auto
--output-directory ~/ai/comfy/output
# Then open http://127.0.0.1:8188 in a browser
What you see is a graph with seven nodes wired in a line: Load Checkpoint → CLIP Text Encode (positive) → CLIP Text Encode (negative) → Empty Latent Image → KSampler → VAE Decode → Save Image. Every box is a Python function, every wire is a tensor. Click Queue Prompt. On an RTX 4090, an SDXL 1024×1024 image at 30 steps with the dpmpp_2m sampler completes in roughly 4 to 6 seconds end to end.
Expected console output for the first successful run looks like this.
got prompt
model_type EPS
Using pytorch attention in VAE
Working with z of shape (1, 4, 32, 32) = 4096 dimensions.
loaded straight to GPU
Requested to load SDXLClipModel
Loading 1 new model
loaded completely 0.0 5159.6 True
Requested to load SDXL
Loading 1 new model
loaded completely 0.0 4897.0 True
100%|###############################| 30/30 [00:04<00:00, 7.21it/s]
Requested to load AutoencoderKL
Loading 1 new model
loaded completely 0.0 159.6 True
Prompt executed in 5.83 seconds
Step 7: Build a Reusable SDXL Workflow with LoRA
The default graph is a starting point, not a workflow you ship. A real SDXL workflow adds a LoRA loader for style, sets cfg and the sampler explicitly, fixes the resolution to a tested SDXL size, and saves with a meaningful filename prefix. Right-click empty canvas, choose Add Node → loaders → LoadLoRA, and wire it between Load Checkpoint and the two CLIP Text Encode nodes.
You will also want to save the graph as JSON so it is reproducible. Click the menu, Workflow → Save As, and put it in a project folder under version control. Below is the relevant part of a typical saved SDXL+LoRA workflow JSON, trimmed for readability.
{
"nodes": [
{ "id": 4, "type": "CheckpointLoaderSimple",
"widgets_values": ["sd_xl_base_1.0.safetensors"] },
{ "id": 10, "type": "LoraLoader",
"widgets_values": ["add_detail_xl.safetensors", 0.6, 0.6] },
{ "id": 6, "type": "CLIPTextEncode",
"widgets_values": ["cinematic photo of a snow leopard on a mossy rock, 50mm, f/2.8, golden hour, sharp focus"] },
{ "id": 7, "type": "CLIPTextEncode",
"widgets_values": ["blurry, low quality, deformed, extra limbs, text, watermark"] },
{ "id": 5, "type": "EmptyLatentImage",
"widgets_values": [1024, 1024, 1] },
{ "id": 3, "type": "KSampler",
"widgets_values": [123456789, "fixed", 30, 6.5, "dpmpp_2m", "karras", 1.0] },
{ "id": 8, "type": "VAEDecode" },
{ "id": 9, "type": "SaveImage",
"widgets_values": ["sdxl/leopard_"] }
]
}
Three values matter more than the others in this workflow. cfg at 6.5 is the SDXL sweet spot; below 5 prompts get ignored, above 9 you get fried colors. The karras scheduler with dpmpp_2m at 30 steps is the standard high-quality combo. LoRA strength at 0.6 is the conservative starting point; bump model strength and clip strength together for stronger style transfer.
Step 8: Run FLUX.1 [dev] for State-of-the-Art Prompt Adherence
FLUX uses a different graph because it splits the model into a UNet, a VAE (called ae.safetensors in the FLUX repo), and two text encoders (CLIP-L and T5-XXL). The simplest way to get a working FLUX graph is to drag the official FLUX example image onto the ComfyUI canvas – ComfyUI extracts the embedded workflow from the PNG metadata.
![Step 8: Run FLUX.1 [dev] for State-of-the-Art Prompt Adherence](https://tech-insider.org/wp-content/uploads/2026/05/step-8-run-flux-1-dev-for-state-of-the-art-prompt-adherence-3.webp)
A working FLUX.1 [dev] fp8 graph contains the following nodes.
- UNETLoader:
flux1-dev.safetensors, weight_dtypefp8_e4m3fn - DualCLIPLoader:
t5xxl_fp8_e4m3fn.safetensors+clip_l.safetensors, typeflux - VAELoader:
ae.safetensors - CLIPTextEncode: positive prompt only – FLUX ignores negatives
- EmptyLatentImage: 1024×1024 (FLUX handles non-square sizes well)
- KSampler: 20 steps,
eulersampler,simplescheduler, cfg 1.0 - VAEDecode + SaveImage
The two FLUX-specific gotchas: cfg must be 1.0 because FLUX is distilled and amplifies guidance internally, and the negative prompt branch should be empty because FLUX’s default conditioning system does not consume it. On an RTX 4090, FLUX.1 [dev] fp8 at 1024×1024 with 20 steps lands around 12 to 18 seconds per image, depending on whether the T5 encoder is already cached in VRAM.
Step 9: Image-to-Image, Inpainting, and ControlNet
The three workflows that most teams use after text-to-image are img2img (change an existing image), inpainting (mask out a region and regenerate it), and ControlNet (constrain generation to a depth map, pose, or edge map). All three are variations on the same SDXL graph with one or two extra nodes.
Image-to-Image
Replace EmptyLatentImage with LoadImage → VAEEncode, then set the KSampler’s denoise value below 1.0. A denoise of 0.5 keeps roughly half the original composition and lets the prompt push the rest; 0.3 is “polish only”; 0.8 is a near-rewrite.
Inpainting
Use the LoadImage node, draw a mask in the built-in mask editor, and feed it through VAEEncodeForInpaint. ComfyUI ships a working inpaint example in the Templates → Image → Inpaint menu inside the web UI; that template handles mask blurring and the correct VAE encode path so you do not have to reinvent it.
ControlNet
Download an SDXL-compatible ControlNet such as controlnet-canny-sdxl-1.0.safetensors into models/controlnet. Add ControlNetLoader → ControlNetApply between the positive prompt and the KSampler, and feed it the preprocessed control image. Strength 0.6–0.8 holds the composition while still letting the prompt do its job.
Step 10: Performance Tuning and VRAM Modes
ComfyUI exposes three command-line flags that materially change how a model fits into memory and how fast it runs. Use them when you would otherwise see an out-of-memory error or when you want maximum throughput on a workstation.
# Aggressive low-VRAM mode: offload aggressively to CPU
python main.py --lowvram --listen 127.0.0.1
# Absolute minimum VRAM: layer-by-layer load (very slow)
python main.py --novram
# Maximum throughput: keep everything on GPU
python main.py --highvram
# Disable the smart memory manager for deterministic profiling
python main.py --disable-smart-memory
# Use a specific GPU on a multi-GPU box
CUDA_VISIBLE_DEVICES=1 python main.py --listen 127.0.0.1
On a 24 GB RTX 4090, running with no flags is correct; ComfyUI’s smart memory manager keeps the UNet hot and offloads text encoders between prompts. On a 12 GB RTX 4070, add --lowvram for FLUX or SD 3.5 Large. On a 6 GB or 8 GB GPU, stick to SDXL or SD 1.5 and use --lowvram; FLUX is technically possible with --novram but generations exceed 90 seconds and the UX becomes painful.
| GPU | VRAM | Best Model | Recommended Flags | Approx 1024×1024 time |
|---|---|---|---|---|
| RTX 3060 | 12 GB | SDXL, SD 3.5 Medium | default | ~12 s SDXL |
| RTX 4070 | 12 GB | SDXL, FLUX fp8 | –lowvram for FLUX | ~7 s SDXL, ~25 s FLUX |
| RTX 4080 | 16 GB | FLUX, SD 3.5 Large | default | ~5 s SDXL, ~18 s FLUX |
| RTX 4090 | 24 GB | All | –highvram | ~4 s SDXL, ~13 s FLUX |
| RTX 5090 | 32 GB | All + video | –highvram | ~3 s SDXL, ~9 s FLUX |
| Apple M3 Max | unified 64 GB | SDXL, FLUX fp8 | default (MPS) | ~25 s SDXL |
Step 11: Custom Nodes — The Power-User Layer
ComfyUI’s custom node ecosystem is what makes this a serious tool rather than a hobby project. A handful of node packs cover most production needs and are install-once-and-forget. Install them through ComfyUI Manager’s Install Custom Nodes menu rather than cloning manually, because Manager handles the dependency requirements files and the restart trigger.
- rgthree-comfy: better seed handling, fast group mute/bypass, context switches
- ComfyUI-Impact-Pack: face detail enhancement, segmentation, region prompts
- ComfyUI-Crystools: real-time VRAM and GPU monitor in the UI
- ComfyUI-VideoHelperSuite: frame loading, ffmpeg-based video export
- comfyui-tooling-nodes: API-friendly nodes for headless workflows
- ComfyUI-AnimateDiff-Evolved: motion modules for short video clips
- was-node-suite-comfyui: image manipulation, text, file I/O
Important hygiene: when you install custom nodes, pin Manager to Stable channel rather than Latest, and snapshot your custom_nodes directory with the Manager’s built-in snapshot tool before any major change. Custom nodes can and do introduce breaking changes that ripple through workflows.
Step 12: Drive ComfyUI from Python via the HTTP API
ComfyUI describes itself in its GitHub repo as “GUI, api and backend” for a reason: every workflow you build in the browser can be submitted as JSON through an HTTP API. This is what makes ComfyUI usable as a render farm or as the image step of a larger AI pipeline.

The flow has four parts: convert your workflow from the editor format to the API format by enabling Settings → Enable Dev Mode Options in the UI, then clicking Save (API Format); submit the JSON to /prompt; poll /history/{prompt_id} until the prompt completes; download each output image from /view.
# comfy_client.py
import json
import time
import uuid
import urllib.parse
from pathlib import Path
import requests
COMFY = "http://127.0.0.1:8188"
CLIENT_ID = str(uuid.uuid4())
def submit(workflow: dict) -> str:
r = requests.post(
f"{COMFY}/prompt",
json={"prompt": workflow, "client_id": CLIENT_ID},
timeout=30,
)
r.raise_for_status()
return r.json()["prompt_id"]
def wait(prompt_id: str, poll: float = 1.0, timeout: float = 600.0) -> dict:
start = time.time()
while time.time() - start < timeout:
r = requests.get(f"{COMFY}/history/{prompt_id}", timeout=10)
r.raise_for_status()
data = r.json()
if data:
return data[prompt_id]
time.sleep(poll)
raise TimeoutError(f"prompt {prompt_id} did not finish in {timeout}s")
def download(filename: str, subfolder: str, type_: str, dest: Path) -> Path:
qs = urllib.parse.urlencode(
{"filename": filename, "subfolder": subfolder, "type": type_}
)
r = requests.get(f"{COMFY}/view?{qs}", timeout=60)
r.raise_for_status()
dest.parent.mkdir(parents=True, exist_ok=True)
dest.write_bytes(r.content)
return dest
if __name__ == "__main__":
wf = json.loads(Path("workflows/sdxl_leopard_api.json").read_text())
# Inject seed and prompt at runtime
wf["3"]["inputs"]["seed"] = int(time.time())
wf["6"]["inputs"]["text"] = (
"studio portrait of a red panda eating bamboo, 85mm, soft window light"
)
prompt_id = submit(wf)
print("submitted:", prompt_id)
result = wait(prompt_id)
for node_id, node_out in result["outputs"].items():
for image in node_out.get("images", []):
out = Path("output") / image["filename"]
download(image["filename"], image["subfolder"], image["type"], out)
print("saved:", out)
The same pattern works for WebSocket-based streaming via /ws?clientId=<CLIENT_ID> if you want step-by-step progress for a long-running FLUX prompt. For batch rendering, run two ComfyUI processes on two GPUs with different --port values and a small round-robin scheduler in front; this scales linearly with GPU count up to the limits of your storage I/O.
Step 13: Package the Whole Project for Reproducibility
The last step is the one most ComfyUI tutorial guides skip: making the whole thing reproducible. A working ComfyUI install includes a frozen ComfyUI commit, pinned Python dependencies, a manifest of custom nodes, and a manifest of model hashes. Capture them all in a single project directory you can clone to a second machine and have it work without manual fiddling.
# Project layout
my-comfy-project/
|-- README.md
|-- pyproject.toml # pinned Python deps for the API client
|-- workflows/
| |-- sdxl_leopard.json # editor format
| |-- sdxl_leopard_api.json # API format
| |-- flux_portrait_api.json
| `-- sd35_landscape_api.json
|-- scripts/
| |-- comfy_client.py
| |-- batch_render.py
| `-- verify_models.py
|-- manifests/
| |-- comfyui_version.txt # "v0.22.0"
| |-- custom_nodes.json # list + commit hashes (Manager snapshot)
| `-- models.sha256 # sha256 of every safetensors file
`-- docker/
|-- Dockerfile
`-- docker-compose.yaml
A 30-line verify_models.py that walks models/, computes sha256 hashes, and diffs them against manifests/models.sha256 turns a corrupted FLUX download into a single line of output instead of a four-hour debugging session. ComfyUI Manager’s “Snapshot” feature gives you the custom node manifest with one click; commit it to git alongside your workflows.
Common Pitfalls and Fixes
The five mistakes that swallow the most hours in a typical ComfyUI tutorial install, with the actual fix that resolves each.
- Mixing Python versions. Installing nodes against Python 3.13 and then launching with 3.10. Fix: always activate the project’s
.venvbefore runningpiporpython main.py; add adirenvrule to your project folder. - Wrong PyTorch CUDA wheel.
pip install torchwithout--index-urlon Windows pulls the CPU wheel and you wonder why generations are 60× slower. Fix: always use the explicit--index-urlfrom the official PyTorch installer matrix. - Saving the editor JSON and submitting it to
/prompt. The HTTP API expects the “API format” export, which is a different JSON shape. Fix: enable Dev Mode Options and use Save (API Format). - Forgetting that FLUX has
cfg=1.0. Copy-pasting an SDXL KSampler into a FLUX workflow leavescfgat 7, which gives FLUX a blown-out, oversaturated look. Fix: setcfgto 1.0 on FLUX KSampler nodes. - Custom node Python dependency conflicts. Some node packs pin
numpy<2.0; others requirenumpy>=2.0. Fix: install one breaking pack at a time, take a Manager snapshot after each, and remove the offending pack if conflicts cannot be resolved.
Output Example: Full ComfyUI v0.22.0 Boot Log
A successful first launch of ComfyUI v0.22.0 on an RTX 4090 with Manager installed prints something close to the following. Save it as your baseline so future logs are easy to diff against.
** ComfyUI startup time: 2026-04-25 11:08:14.317
** Platform: Linux
** Python version: 3.12.7
** Python executable: /home/user/ai/comfy/.venv/bin/python
** ComfyUI Path: /home/user/ai/comfy/ComfyUI
** Log path: /home/user/ai/comfy/ComfyUI/comfyui.log
Prestartup times for custom nodes:
0.6 seconds: /home/user/ai/comfy/ComfyUI/custom_nodes/ComfyUI-Manager
Total VRAM 24564 MB, total RAM 64162 MB
pytorch version: 2.7.0+cu124
Set vram state to: NORMAL_VRAM
Device: cuda:0 NVIDIA GeForce RTX 4090 : cudaMallocAsync
Using pytorch attention
ComfyUI version: 0.22.0
[Prompt Server] web root: /home/user/ai/comfy/ComfyUI/web
Import times for custom nodes:
0.0 seconds: /home/user/ai/comfy/ComfyUI/custom_nodes/websocket_image_save.py
0.7 seconds: /home/user/ai/comfy/ComfyUI/custom_nodes/ComfyUI-Manager
Starting server
To see the GUI go to: http://0.0.0.0:8188
Troubleshooting Guide
If something breaks, work through this list in order. Most issues collapse to one of these nine categories.

- “CUDA out of memory” during sampling. Lower image resolution to 768×768, drop batch size to 1, switch to fp8 weights, or add
--lowvram. If FLUX still OOMs on 12 GB, switch to FLUX.1 [schnell] which fits in 8 GB. - Black images on output. Almost always a VAE mismatch. SDXL needs the SDXL VAE, FLUX needs
ae.safetensors. Check the VAE Loader node, or use the VAE baked into the checkpoint by leaving Load Checkpoint wired into VAE Decode. - Workflow opens with red “missing nodes” boxes. Click Manager → Install Missing Custom Nodes. Restart ComfyUI. If a node still fails, it has been renamed or removed upstream – check the workflow author’s repo for an updated version.
- “Error: Could not allocate tensor” on Apple Silicon. Add
PYTORCH_ENABLE_MPS_FALLBACK=1to the environment and relaunch. MPS lacks a few ops that the fallback covers on CPU. - Generation completes but no image appears. Check the Save Image filename prefix – if it contains a slash to a folder that does not exist, ComfyUI silently fails. Confirm the
--output-directorypath is writable. - Browser shows “CORS error” from a remote tab. Launch with
--enable-cors-header '*'in development, or put ComfyUI behind a reverse proxy that adds the header. - Custom node refuses to import. Inspect ComfyUI’s console for the actual Python traceback. Nine times out of ten it is a missing
pip install -r requirements.txtinside that node’s folder. - Hugging Face download returns 401. You forgot to accept the model’s license on the model card page, or your
huggingface-cli logintoken expired. Regenerate a read token and re-login. - Manager UI is empty or fails to refresh. Delete
custom_nodes/ComfyUI-Manager/.cacheand restart ComfyUI; Manager rebuilds its registry on next launch.
Advanced Tips for Production Workflows
Once the basics work, a handful of advanced techniques separate hobby installs from production-grade ComfyUI deployments. None of these are exotic, but they compound.
- Use subgraphs for repeated logic. ComfyUI v0.22.0 has stable subgraph support: select a group of nodes, right-click, Convert to Subgraph. Wrap a face-fix pipeline once and reuse it across five workflows.
- Cache CLIP and VAE between prompts. The smart memory manager already does this on default settings; do not pass
--disable-smart-memoryunless you are profiling. - Pin model dtypes explicitly. When you ship a workflow to a teammate with a smaller GPU, set
weight_dtypeon UNet loaders tofp8_e4m3fnso they can run it without modification. - Use queue dependencies for chained renders. The
/promptendpoint accepts afrontflag to jump the queue, useful for an interactive preview path on a server that is otherwise batch-rendering. - Add ControlNet preprocessors as separate nodes. Do not bake Canny or Depth preprocessing into your generation graph; precompute the control images and feed them as inputs. You save 1–2 seconds per image and gain reproducibility.
- Profile end-to-end, not just sampling. A workflow that takes 6 seconds to sample but 12 seconds to load the model from cold disk is bottlenecked on I/O. Move models to NVMe.
- Treat workflows as code. Version-control the API JSON files, code-review changes, and tag releases. The same engineering hygiene you apply to backend services applies here.
ComfyUI vs Other Diffusion Front-Ends
If you are coming from another UI, the table below sets expectations on the trade-offs. None of these are wrong choices; they target different workflows.
| Tool | Interface | Best For | Day-0 Model Support | API | License |
|---|---|---|---|---|---|
| ComfyUI v0.22.0 | Node graph | Custom pipelines, automation, research | Excellent (canonical for FLUX, SD 3.5) | Yes, JSON over HTTP/WebSocket | GPL-3.0 |
| Automatic1111 web UI | Tabbed form | Quick SD 1.5 / SDXL iteration | Lags by weeks for new arch | Yes, but limited | AGPL-3.0 |
| Forge / reForge | Tabbed form | Memory-efficient SDXL / FLUX | Good | Same as A1111 | AGPL-3.0 |
| InvokeAI | Hybrid GUI + canvas | Inpainting / outpainting / iterate on artboards | Moderate | Yes, REST | Apache-2.0 |
| Fooocus | Single page | Beginners, SDXL one-click | SDXL only | No | GPL-3.0 |
| SwarmUI | Hybrid (uses ComfyUI as backend) | Form UX on top of ComfyUI graphs | Same as ComfyUI | Yes | MIT |
The pattern that has emerged in 2026 is that ComfyUI is the backend; SwarmUI and a growing number of in-house front-ends consume it through the API. If you want the form-style UX without giving up the node graph’s power, run ComfyUI as a daemon and put a thin UI in front of it.
Running ComfyUI in Docker for a Clean Server Install
For a headless server, Docker plus the NVIDIA Container Toolkit removes most of the version-drift footguns. The Dockerfile below mirrors the steps above but bakes them into a single reproducible image.
# docker/Dockerfile
FROM nvidia/cuda:12.4.1-cudnn-runtime-ubuntu22.04
ENV DEBIAN_FRONTEND=noninteractive
PIP_DISABLE_PIP_VERSION_CHECK=1
PYTHONDONTWRITEBYTECODE=1
RUN apt-get update && apt-get install -y --no-install-recommends
python3.12 python3.12-venv python3.12-dev
git build-essential ffmpeg curl ca-certificates &&
ln -sf /usr/bin/python3.12 /usr/local/bin/python &&
rm -rf /var/lib/apt/lists/*
WORKDIR /opt
RUN python -m venv /opt/venv
ENV PATH=/opt/venv/bin:$PATH
RUN pip install --upgrade pip wheel setuptools &&
pip install torch==2.7.0 torchvision==0.22.0
--index-url https://download.pytorch.org/whl/cu124
RUN git clone --depth 1 --branch v0.22.0
https://github.com/comfyanonymous/ComfyUI.git /opt/ComfyUI &&
cd /opt/ComfyUI && pip install -r requirements.txt
RUN git clone --depth 1 https://github.com/ltdrdata/ComfyUI-Manager.git
/opt/ComfyUI/custom_nodes/ComfyUI-Manager &&
pip install -r /opt/ComfyUI/custom_nodes/ComfyUI-Manager/requirements.txt
WORKDIR /opt/ComfyUI
EXPOSE 8188
CMD ["python", "main.py", "--listen", "0.0.0.0", "--port", "8188"]
Build with docker build -t comfy:0.22 docker/ and run with docker run --rm -p 8188:8188 --gpus all -v $PWD/models:/opt/ComfyUI/models comfy:0.22. Bind-mount the models/ directory so a 60 GB model library is not rebaked into every image; the container itself is then under 8 GB.
FAQ
Is ComfyUI free to use commercially?
ComfyUI itself is licensed under GPL-3.0, which permits commercial use. The model weights are a separate question: SDXL 1.0 is permissive, FLUX.1 [dev] is non-commercial only without a commercial license from Black Forest Labs, and Stable Diffusion 3.5 has its own community license with thresholds based on annual revenue. Always read the model card before deploying.
Can I run ComfyUI without an NVIDIA GPU?
Yes. Apple Silicon (M-series) runs ComfyUI via PyTorch MPS at roughly one-fifth to one-third the speed of an equivalent NVIDIA card. AMD GPUs work on Linux via ROCm 6.2, with most workflows on RX 7900 XTX class hardware. CPU-only mode works for SD 1.5 and is too slow for SDXL or FLUX.
What is the difference between ComfyUI Desktop and the GitHub version?
ComfyUI Desktop is an Electron-style native app that bundles Python, ComfyUI, and Manager into a one-click installer. The GitHub version is what you cloned in Step 3. Desktop is the right choice for non-technical users; the GitHub version is the right choice for anything you intend to script, automate, or deploy to a server.
How do I share a workflow with someone else?
The PNG images ComfyUI writes contain the entire workflow JSON in their metadata. Drag the PNG onto another ComfyUI canvas and it reloads. For programmatic use, share the .json file directly. For full reproducibility, include the model SHA-256 hashes and a Manager snapshot.
Why does ComfyUI run faster than Automatic1111 on the same model?
Two reasons. First, ComfyUI’s graph executor only re-runs nodes whose inputs changed, so iterating on a prompt does not redo the model load. Second, ComfyUI’s memory manager keeps the UNet on GPU between prompts when there is room. On equivalent hardware, ComfyUI usually finishes SDXL generations 15–30 percent faster than A1111 in practice.
Can ComfyUI handle video generation?
Yes. AnimateDiff-Evolved gives you motion modules on top of SD 1.5 and SDXL. Newer video diffusion models such as the Wan family ship reference ComfyUI workflows for short clips. Real-time video generation is still out of reach on consumer hardware in 2026.
How does ComfyUI compare to running models in Python directly?
For one-off scripts, the Hugging Face diffusers library is cleaner. For complex pipelines – LoRA + ControlNet + face fix + upscale – ComfyUI’s graph is easier to maintain than a 400-line Python script and faster to iterate on. Many teams use both: ComfyUI for prototyping, then port the final graph to diffusers when they need tight integration into a Python service.
Where can I find production-quality workflow JSON files?
The official ComfyUI documentation publishes reference workflows for every supported model family. The official ComfyUI examples site hosts PNG-embedded workflows you can drag into the canvas. Community workflows live on the ComfyUI workflow registry (accessible from the Manager) and on Civitai.
This ComfyUI tutorial covered the 13 steps from a clean machine to a reproducible, API-driven diffusion stack on ComfyUI v0.22.0. The workflows you built here – SDXL with LoRA, FLUX.1 [dev] in fp8, image-to-image, inpainting, ControlNet, and the Python API client – cover the patterns you will reuse across almost every diffusion project in 2026. Keep your Manager snapshot, your model hashes, and your workflow JSON under version control, and the next major model release becomes a one-day upgrade instead of a one-week rebuild.





