It looks perfect at thumbnail size. Then you open it full screen.
Why one-shot high resolution blurs faces, and the two-pass fix that actually works
The thumbnail looked incredible. A portrait, warm window light, an earring catching the glow. You open the full-size file to actually use it and the earring is a smudge of pink, the eyelashes on the near eye have fused into one dark wedge, and the cable knit on the sweater has gone flat and waxy, like the render gave up the second nobody was looking closely.
This isn't a bad seed and it isn't a settings typo. It's what happens when you ask a diffusion model to generate a big image in a single pass. Every checkpoint has a resolution it was actually trained and tuned around, roughly 512x512 for the SD 1.5 family and roughly 1024x1024 for SDXL. Stay near that number and the model knows what it's doing. Push straight past it, ask for something twice the size in one shot, and you're not just getting a bigger version of the same image. You're asking the model to fill space it was never taught to compose, and it starts improvising. Detail goes soft because there's more canvas than the model has real information for, and at the more extreme end you get the classic giveaway of a stretched generation: a second faint head, a spare hand, a torso that repeats.
The fix that's built into both major toolchains is called hires fix, and it does something almost boring in concept. AUTOMATIC1111's own documentation describes it plainly: a convenience option that partially renders your image at a lower resolution, upscales it, and then adds detail at a high resolution. That's the whole trick. Generate at the size the model is actually good at, upscale the result, then run a second, lighter generation pass over the upscaled image so it can paint in detail that matches the new pixel count instead of just stretching what it already made.
ComfyUI ships the identical idea as an official example workflow, usually called two-pass txt2img. The structure is the same regardless of which interface you use: a first sampler builds the image small, a latent or pixel-space upscaler enlarges it, and a second sampler runs another pass on the enlarged version. It's a documented, standard part of the pipeline, not a workaround someone found by accident.
Everything about whether this looks great or looks wrong comes down to the denoising strength on that second pass. This is a separate slider from whatever denoise you used on your base generation, and it controls how much freedom the second pass has to repaint what's already there.
Set it near zero and the upscale changes almost nothing. You'll have more pixels, but the earring is still a smudge, just a bigger one, because the model never got permission to actually add anything. Set it near 1.0 and you've basically told the model to regenerate the image from scratch at the new size, which brings back the very problem you were trying to avoid: the face can drift, the sweater might change color, the earring might migrate to the other ear entirely, because at that strength the second pass barely resembles a refinement anymore.
The workable middle sits around 0.5. That's low enough to keep the composition, the pose, and the identity locked to your first pass, and high enough to let the model actually paint in lash lines, knit texture, and skin pores that the low-res version never had room for. AUTOMATIC1111 defaults this slider to 0.7, which a lot of people find too aggressive and end up dialing back.
It's a checkbox, literally labeled Hires. fix, sitting under the main generation settings. Turn it on and you get a target resolution or a scale multiplier, an upscaler dropdown, and its own denoising strength slider separate from anything else on the page. The upscaler list includes several latent variants (plain Latent, Latent antialiased, Latent bicubic, Latent bicubic antialiased, Latent nearest) plus every upscaler you've installed on the Extras tab, which is where the ESRGAN-family options live. Pick a latent option for speed and a tight match to your checkpoint, or a pixel-space one when you want crisp edges on things like jewelry and fabric weave.
There's no single checkbox here since ComfyUI is node-based, but the shape of the graph is simple once you've seen it once. An Empty Latent Image node sets your small base resolution, feeding a first KSampler at full denoise, the same way any text-to-image generation works. From there, either a Latent Upscale node enlarges the result while staying in latent space, or you route through VAE Decode, a pixel-space upscale model, and VAE Encode to get back into latent space using the sharper pixel method. Either path feeds into a second KSampler, and that node's denoise value is exactly the dial described above. Decode the final latent and save.
| Situation | Starting point |
|---|---|
| Portrait with fine detail: lashes, jewelry, embroidery | Base gen near the model's native resolution, then 1.5x to 2x hires fix, denoise ~0.45 to 0.5 |
| Latent upscaler, want speed and tight coherence | Denoise closer to 0.6 to 0.7 |
| ESRGAN / 4x-UltraSharp, want crisp edges | Denoise 0.3 to 0.45, it's already sharpened before the pass starts |
| Face or pose keeps drifting after upscale | Denoise is too high for your upscaler. Lower it in 0.05 steps |
| Bigger file, same soft detail as before | Denoise is too low. The second pass isn't being given room to add anything |
Hires fix earns its keep at generation time, before you've committed to an image. It's not a substitute for the finishing tools you'd reach for after the fact. If a single hand still comes out wrong after the second pass, that's a job for targeted inpainting, not another full hires pass. And if you're chasing print-size output well beyond what a second sampling pass is meant to add, a dedicated upscaling workflow for final output resolution is the better next step. Hires fix solves one specific problem: the gap between the size a model is good at and the size you actually want, closed with real repainted detail instead of a stretched, softer copy of the same low-res image.
Go back to that portrait. Generate it small first, upscale by around 1.5x, run the second pass at a denoise around 0.45 with a latent upscaler, and the earring stops being a smudge and becomes an actual stud with a highlight on it. The lashes separate. The knit gets its texture back. Same prompt, same seed even, just given room to finish the job in two passes instead of one.