Ultimate SD Upscale
Tiled img2img upscaling that hits 4K on modest VRAM
- image
- model
- positive
- negative
- vae
- upscale_model
- IMAGE
You want a big, detailed image, but generating straight at 4K on your checkpoint gives you duplicated torsos and repeated hands. That's the wall every diffusion model hits above its native resolution. UltimateSDUpscale is the classic way around it: enlarge the image first, then chop it into tiles the model was trained on and repaint each one with a light img2img pass. Your GPU only ever sees one tile at a time, so a 6GB card can push a picture to print size without running out of memory.
This is ssitu's ComfyUI port of Coyote-A's Ultimate SD Upscale script, which was a bit of a phenomenon in the Automatic1111 days ("we have a new Upscaler in Automatic and it's crazy"). The mechanism has aged well because it's just good plumbing, not a model that goes stale.
How it works
Two stages, back to back. First it takes your image and upscales the whole thing by upscale_by using an ESRGAN-type upscale_model (something like 4x-UltraSharp). That gets you the pixels, fast, but a plain ESRGAN enlarge looks a little flat and smooth because it can't invent real detail. So the second stage splits that enlarged image into overlapping tiles (512x512 by default) and runs a low-denoise img2img pass on each tile with your actual checkpoint. Because each tile is back down at a resolution the model understands, it paints in believable skin texture, fabric weave, hair, and small detail, then blends the tiles back together with a seam fix. Pixels from the ESRGAN pass, real detail from the diffusion pass.
The whole point is that the diffusion model never sees the giant image, only tile-sized chunks, which is why this runs on hardware that could never denoise a 4K latent directly.
The inputs and outputs that matter
You're basically wiring up a KSampler with three upscale-specific extras. The ones a beginner actually touches:
upscale_model(required, UPSCALE_MODEL): feed it a "Load Upscale Model" node pointing at an ESRGAN model inmodels/upscale_models. 4x-UltraSharp is the community default for general use; anime has its own variants. This does the initial enlarge.upscale_by(default 2): your scale factor. 2 is the sweet spot; the node handles the tiling automatically at any size.denoise(default 0.2): the single most important dial. This controls how much the img2img pass is allowed to change each tile. Low (0.15 to 0.3) adds detail while staying faithful. Crank it and each tile starts inventing content that doesn't agree with its neighbors.
The rest is a standard sampler: model, positive, negative, vae, seed, steps, cfg, sampler_name, scheduler. Reuse the settings from your generation, though many people drop the default cfg of 8 a bit for a detail pass. tile_width/tile_height should roughly match your model's native res (512 for SD1.5, 1024-ish for SDXL). seam_fix_mode (try "Half Tile" or "Half Tile + Intersections") plus mask_blur and tile_padding clean up the joins between tiles. The single output is one IMAGE, which you send straight to a Save/Preview node.
Installing it
ComfyUI Manager is the easy path: open the Custom Nodes Manager, search "UltimateSDUpscale", install, restart. Or from a terminal:
cd ComfyUI/custom_nodes
git clone https://github.com/ssitu/ComfyUI_UltimateSDUpscale
then restart ComfyUI. (comfy-cli users: comfy node install comfyui_ultimatesdupscale.) The pack itself is lightweight Python with no heavy dependencies and ships no models, but you do need to supply an upscale model separately, drop it in models/upscale_models. The nodes land under image/upscaling in the node menu, and there are example workflows under Templates > Extensions.
Common issues and troubleshooting
The classic failure is faces appearing in random tiles. When denoise is too high, the model treats ambiguous texture (foliage, gravel, fabric) as face-like and hallucinates one. The fix is almost always to lower denoise; keep it around 0.2 and only nudge up if detail is lacking. High denoise also gives you visible seams and patchwork, tiles that clearly disagree with each other, because each was allowed to drift too far from the source. If seams persist even at sane denoise, raise mask_blur/tile_padding and switch seam_fix_mode to one of the Half Tile options. For stubborn content drift on tough sources, feeding a ControlNet Tile alongside this keeps every tile locked to the original, which the community treats as the reliable-photorealism recipe.
One honest note on where this sits in 2026: for pure detail on a clean image, SeedVR2 has largely taken over and people report it running faster than Ultimate SD Upscale with better results. Where UltimateSDUpscale still wins is control and reach: arbitrary output size on limited VRAM, your exact checkpoint and prompt driving the detail, and no new model to download. That's a real niche, and it's why this node is still everywhere.
Inputs (26)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | The image to upscale. | |
| model | MODEL | The model to use for image-to-image. | |
| positive | CONDITIONING | The positive conditioning for each tile. | |
| negative | CONDITIONING | The negative conditioning for each tile. | |
| vae | VAE | The VAE model to use for tiles. | |
| upscale_by | FLOAT | 2.000.05–4 | The factor to upscale the image by. |
| seed | INT | 00–18446744073709550000 | The seed to use for image-to-image. |
| steps | INT | 201–10000 | The number of steps to use for each tile. |
| cfg | FLOAT | 8.000–100 | The CFG scale to use for each tile. |
| sampler_name | COMBO | The sampler to use for each tile. | |
| scheduler | COMBO | The scheduler to use for each tile. | |
| denoise | FLOAT | 0.200–1 | The denoising strength to use for each tile. |
| upscale_model | UPSCALE_MODEL | The upscaler model for upscaling the image. | |
| mode_type | COMBO | The tiling order to use for the redraw step. | |
| tile_width | INT | 51264–8192 | The width of each tile. |
| tile_height | INT | 51264–8192 | The height of each tile. |
| mask_blur | INT | 80–64 | The blur radius for the mask. |
| tile_padding | INT | 320–8192 | The padding to apply between tiles. |
| seam_fix_mode | COMBO | The seam fix mode to use. | |
| seam_fix_denoise | FLOAT | 1.000–1 | The denoising strength to use for the seam fix. |
| seam_fix_width | INT | 640–8192 | The width of the bands used for the Band Pass seam fix mode. |
| seam_fix_mask_blur | INT | 80–64 | The blur radius for the seam fix mask. |
| seam_fix_padding | INT | 160–8192 | The padding to apply for the seam fix tiles. |
| force_uniform_tiles | BOOLEAN | true | Force all tiles to be the same as the set tile size, even when tiles could be smaller. This can help prevent the model from working with irregular tile sizes. |
| tiled_decode | BOOLEAN | false | Whether to use tiled decoding when decoding tiles. |
| batch_size | INT | 11–4096 | The number of tiles to process in a batch. Higher values can reduce processing time but use more VRAM. Yields different results than individual tiles. Only affects the main redraw step, not the seam fix step. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | The final upscaled image. |