Mastering ComfyUI — Part 6: Upscaling & Post-Processing
Get higher-resolution, higher-detail final images out of ComfyUI without cranking up base generation resolution — covering image-model upscaling, latent hires-fix, and how to combine them.
Goal for this part: get higher-resolution, higher-detail final images out of ComfyUI without just cranking up your base generation resolution (which usually makes composition worse, not better).
Previous: Part 5 — Advanced Conditioning
Why you don't just generate at high resolution directly
Every checkpoint has a native resolution range it was trained on — SDXL-family
models around 1024×1024 (or equivalent total pixel counts at other aspect
ratios), Flux similarly. Push Empty Latent Image well past that range and you
don't get a sharper version of the same image — you tend to get duplicated
subjects, warped anatomy, or repeated background elements, because the model is
being asked to compose at a scale it never learned.
The standard solution is to generate at a resolution the model actually understands, then upscale afterward as a separate step. This also happens to be more efficient: a full generation at 2x resolution costs far more compute than generating at native resolution and upscaling the result.
Two different kinds of upscaling
Image upscaling (post-decode) — happens after VAE Decode, on the actual
pixel image. Uses a dedicated upscale model (ESRGAN-family models are the most
common) loaded via Load Upscale Model, then applied with an Upscale Image (using model) node. This is a pure image-processing step — it sharpens and
enlarges based on what the upscale model learned about turning low-res detail
into high-res detail, but it can't fix compositional problems, because the model
has already been decoded into final pixels.
Latent upscaling (pre-decode, "hires fix") — happens before VAE Decode,
directly on the sampler's latent output. You resize the latent, then run it
through a second KSampler pass at a low denoise value (typically 0.3–0.5).
Because this second pass is still a real (partial) diffusion pass, it can add and
refine detail rather than just interpolating pixels — sharper texture, cleaner
fine detail, better-defined edges — while the low denoise keeps the overall
composition intact from the first pass.
Which one should you actually use? Latent upscaling ("hires fix") gives noticeably better detail quality because it's genuinely regenerating detail, not just enlarging pixels. Image upscaling is simpler, faster, and safer when you just want a bigger file without touching content — e.g., preparing a final image for print or a video pipeline that wants a specific resolution. Many workflows use both: latent upscale first for quality, then a light image upscale afterward if you need a specific final pixel size.
Building the hires-fix pattern
This inserts between your existing KSampler and VAE Decode:
- Your first
KSamplerruns as normal (this is your existing generation, e.g. 1024×1024) and outputsLATENT. - Search and place "Upscale Latent" (sometimes labeled
LatentUpscaleorLatentUpscaleBy). Wire the first KSampler'sLATENToutput into it, and set your target scale —1.5x–2xis the usual range. Going much higher in one step tends to reintroduce the same composition problems you're trying to avoid; if you want a bigger jump, chain two smaller upscale passes instead of one large one. - Place a second
KSampler. Wire the upscaled latent into itslatent_imageinput, and reconnect the samemodel,positive, andnegativeinputs from your first pass. - Set this second KSampler's
denoiselow — 0.3 to 0.5. This is the setting that makes the whole technique work: high enough to actually add detail, low enough that it doesn't repaint the image and drift away from your first pass's composition. Aseedmatching or differing from your first pass both work here — it doesn't need to match, since you're refining, not reproducing. - Wire the second KSampler's
LATENToutput intoVAE Decode, same as any single-pass workflow.
Denoise too high on the hires pass undoes the point. If you push the second
pass's denoise toward 0.7+, you're not refining detail anymore — you're
substantially regenerating the image at the new resolution, which reopens the
same composition risks (duplicated subjects, warped anatomy) that hires-fix
exists to avoid. If you see a second pass changing things you didn't want
changed, drop denoise before touching anything else.
Adding image-model upscaling
If you want pixel-level upscaling too — either instead of, or after, a hires-fix pass:
- Download an upscale model (
.pthfiles — ESRGAN variants like 4x-UltraSharp are widely used for photorealistic content; illustration-oriented content often pairs better with an upscale model trained on that kind of material) intomodels/upscale_models/. - Place
Load Upscale Modeland select it from the dropdown. - Place
Upscale Image (using model), wireLoad Upscale Model'sUPSCALE_MODELoutput into it, and your decodedIMAGEinto itsimageinput. - Its output feeds
Save Imageas usual.
This node does a fixed multiplier based on what the model was trained for (commonly 4x) — if you need a specific final resolution rather than whatever multiple that produces, follow it with a plain "Image Scale" (or "Resize Image") node set to your exact target dimensions.
Troubleshooting
Hires-fix pass makes the image worse, not better. Almost always denoise set too high on the second KSampler. Drop it to 0.3–0.4 and re-test before changing anything else.
Upscale Image (using model) node errors about mismatched channels or sizes.
Check that the image feeding it actually came through VAE Decode first — this
node expects a standard decoded IMAGE, not a raw latent. A LATENT-to-IMAGE
mismatch is the most common cause of this specific error.
Final output looks oversharpened or has odd texture artifacts. Some upscale models oversharpen fine texture at full strength. If your upscale node has a strength/blend parameter, back it off; otherwise, follow it with a very light blur or a second, gentler upscale model — or reduce reliance on image upscaling and lean more on the latent hires-fix pass instead, since it produces more natural detail.
Next: Part 7 — Custom Nodes & Extensions.
Previous: Part 5 — Advanced Conditioning