Nodes/Best Resolution/Best-Res (area+scale)
ComfyUI Node

Best-Res (area+scale)

Pick one size, get init + upscaled resolutions that both work

By Lex-DRL·Created about a year ago·Updated 5 months ago· 15
Best-Res (area+scale)
    • upscale
    • init_width
    • init_height
    • HD_width
    • HD_height
    square_size1024
    step48
    landscapetrue
    aspect_a16
    aspect_b9
    priorityoriginal
    upscale1.50
    HD_step144

    The hi-res fix is the most reliable way to get a big, clean image: generate at the model's native resolution, then do a second pass at 1.5–2x with low denoising to add detail. The fiddly part isn't the concept - it's the arithmetic. Both the initial resolution and the upscaled resolution need to stay divisible by your step (8, or better, a bigger planning step), and if you pick the initial size badly, the upscaled size ends up in a latent-incompatible hole and you're cropping or outpainting to survive. Best-Res (area+scale) is the pack's answer: one node that plans both sizes together so the whole chain stays clean.

    It's the Best-Res (area) node plus an upscale section. You give it the model's native square size, aspect ratio, orientation, and your target upscale factor - it outputs the init width/height and the HD width/height, plus the exact upscale value to use.

    How it works

    Same core as the area node: normalize your aspect ratio to unit area, multiply by square_size to get the float init dimensions, then multiply by upscale to get the float HD dimensions. The difference is the priority setting, which decides what gets rounded first:

    • original (default) - init size is rounded first, then the HD size is derived from the rounded init and rounded again. The HD image follows the init's ratio most faithfully, but may drift furthest from your desired aspect ratio.
    • desired - both sizes are rounded independently toward the desired ratio. Closest to what you asked, but the two sizes' ratios can differ the most from each other, which can force crop/pad later.
    • upscaled - HD size is rounded first, and init is back-tracked from it. Pick this if the final HD dimensions are what you truly care about.

    After rounding, the node checks whether the HD size can be reached by uniformly scaling the init size. If yes, its upscale output is the precise factor (which may be 1.4783 instead of a clean 1.5 - that's fine). If no, it outputs your original upscale value untouched, and the status readout shows a ⚠️ - that's the signal to route things through the Upscaled Crop/Pad node rather than scaling blindly.

    The inputs you actually set

    • square_size - model's native square: 1024 for SDXL/Flux, 512 for SD 1.5.
    • step - init-side divisibility, default 48.
    • HD_step - upscaled-side divisibility, default 144 (= 8 × 2 × 3 × 3, so a 1.5x init upscale stays clean and the next 1.333x after that stays clean too).
    • upscale - your target HD-fix factor, default 1.5.
    • landscape, aspect_a, aspect_b - ratio and orientation, same as the area node.
    • priority - the rounding order above.

    Outputs and the workflow it feeds

    • init_width, init_height → your first KSampler / Empty Latent Image.
    • upscale → the exact factor for the latent upscale (or image upscale) between passes.
    • HD_width, HD_height → your second KSampler - and into Upscaled Crop/Pad alongside the init sizes, so it can tell you whether crop/pad is needed and how much.

    The intended flow is: generate at init size → upscale by the upscale output → optionally crop/pad per the companion node → second KSampler at HD size with low denoise. The node's on-face status shows both sizes with their step counts and the ✅/⚠️ uniformity verdict, which is genuinely useful while you're tuning.

    Install

    cd ComfyUI/custom_nodes
    git clone https://github.com/Lex-DRL/ComfyUI-BestResolution
    

    or search "Best Resolution" in ComfyUI Manager, install, restart. Only frozendict as a dependency, no model downloads. Like the rest of the pack it's pure arithmetic - it computes, it never draws. Which is exactly why the numbers it gives you are worth trusting: no VRAM, no model quirks, just math that stays clean at every step.

    CategoryBest Resolution

    Inputs (8)

    NameTypeDefaultDescription
    square_sizeINT10241–9223372036854776000The total resolution of the image would be the same as of a square with this side. The width and height would be such to respect aspect ratio, but also be as close as possible to the total number of pixels as in this square image. - 512x512 square (SD 1.5): ~0.25 megapixels - 1024x1024 square (SDXL): ~1 megapixel
    stepINT481–9223372036854776000Both width and height will be divisible by this value - by rounding them to the closest appropriate resolution. The default 48 is (8 * 3 * 2), so it's a safe choice because: - it's compatible with SD1.5/XL downsampling factor (divisible by 8), - it can be upscaled by x1.5 or x1.333 at the first iteration, which is optimal for latent-upscale, - after x1.5 upscale, if you only do x2 later (it's OK for already high resolutions) - it will be divisible by 3 AND 9, which might become handy at that point, where you'll probably use UltimateSDUpscale. Other values worth trying first: 64, 96, 128.
    landscapeBOOLEANtrueSpecifies image orientation: When ON, width is bigger (image is horizontal). When OFF, height is bigger (image is vertical).
    aspect_aFLOAT16Two aspects together define an aspect ratio (16:9, 4:3, etc). Order doesn't matter: image orientation is defined by the 'landscape' toggle. The specified aspect ratio is APPROXIMATE: step parameter has priority over the exact image proportions.
    aspect_bFLOAT9Two aspects together define an aspect ratio (16:9, 4:3, etc). Order doesn't matter: image orientation is defined by the 'landscape' toggle. The specified aspect ratio is APPROXIMATE: step parameter has priority over the exact image proportions.
    priorityCOMBOoriginalDefines what resolution to prioritize, as well as which order to perform rounding in: • desired - first, approximate resolutions are calculated for both initial and upscaled size; then, both are rounded. In both cases, the rounded resolution is closest to the desired one, but aspect ratio might differ the most between sizes. • original - first, initial resolution is calculated and rounded; then, upscaled one is detected from it. Upscaled resolution might differ the most from the desired aspect ratio, but it follows the ratio from initial size as much as possible. • upscaled - vice versa: first, the rounded upscaled resolution is calculated; then, the initial one back-tracked from it.
    upscaleFLOAT1.50
    HD_stepINT1441–9223372036854776000Same as the main `step`, but for the upscaled resolution. 144 = 8 * 2 * 3 * 3

    Outputs (5)

    NameTypeDescription
    upscaleFLOATIf the HD resolution can be achieved by uniformly scaling the initial one (there is "✅" and not "⚠️" in the upscale-line of the status message), outputs this precise upscale-value (might be different from the one originally set on the node itself). Otherwise, outputs the original upscale-value intact. In this case, you shouldn't use it directly and instead should pass it to the "Upscaled Crop/Pad (Best-Res)" node and use the upscale-output from it. In both cases, it won't hurt to use the "Upscaled Crop/Pad (Best-Res)" node and just rely on it's `do_crop` and `do_padding` toggle-outputs.
    init_widthINTWidth for original/initial image
    init_heightINTHeight for original/initial image
    HD_widthINTWidth for the (main/upscaled) HD-image
    HD_heightINTHeight for the (main/upscaled) HD-image