Best-Res (ratio)
Know one side of your image, not the math
- width
- height
Sometimes "pick a resolution by megapixels" isn't the question you're actually asking. You know the image needs a long side of roughly 1600, or a short side of 832, or it has to tile next to another image - and you need the other side to follow from the aspect ratio, then everything rounded to a latent-safe step. That's exactly what Best-Res (ratio) is for. It's the sibling of Best-Res (area): same family, same rounding engine, but instead of fixing the total pixels, it fixes one side of the image.
How it works
You tell it a size and whether that's the big side or the small side of the image. It computes the other side from your aspect ratio - big side 1600 at 16:9 means a small side of 900 - then runs the pack's standard 3-pass rounding so both sides land on multiples of step while keeping the real ratio as close to your requested one as possible. The landscape toggle decides which side is width and which is height. Output is two INTs, width and height, ready for Empty Latent Image.
The inputs that matter
size- the side length you care about. Approximate is fine; the node rounds it.size_is_big- ON meanssizeis the long side (so 1600 wide at 16:9 gives you 1600x900-ish). OFF meanssizeis the short side (832 at 16:9 gives you roughly 1472x832).landscape- ON = width is the bigger side, OFF = height is bigger.aspect_a/aspect_b- the ratio (16 and 9, 4 and 3…). Order doesn't matter; thelandscapetoggle defines orientation.step- the divisibility requirement, default 48. Same story as the rest of the pack: 8 × 2 × 3, so it stays clean through a 1.5x or 1.333x latent upscale.
When this beats the area node
The two nodes sound identical, but they answer different questions:
Best-Res (area)matches total pixel count to the model's training size. Best for keeping the model in its comfort zone - 1MP for SDXL, 0.25MP for SD 1.5.Best-Res (ratio)matches a side length. Best when you have an external constraint: a video frame you're matching, a tile size for tiled workflows, or a target output you just think of in "width" terms. Flux and modern models take a megapixel band, so a 1600-wide 16:9 (about 1.6MP) is perfectly liveable there.
The cost of the ratio approach: it won't hold total pixels near native on its own. For SDXL, a 1600-wide 16:9 is ~1.6MP - over training resolution, so it'll want a hi-res-fix pass to look its best. That's not a bug, it's the input you chose. If you don't have a side constraint, the area node is the better default.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Lex-DRL/ComfyUI-BestResolution
or search "Best Resolution" in ComfyUI Manager, install, and restart. Only frozendict as a dependency, no model downloads - this node is pure arithmetic, so it works with any model you throw at it. It calculates resolution values and nothing else; feed its outputs into your latent-size or conditioning nodes.
One light caveat: because step has priority over exact proportions (a deliberate design choice across this pack), your 16:9 might come out as 16.0:9.1 or similar. The node's on-face readout shows you the real-vs-goal ratio, so a glance tells you how close you landed.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| size | INT | 10241–9223372036854776000 | Approximate size of one of the image sides. Which one - see the 'size_is_big' and 'landscape' toggles. |
| step | INT | 481–9223372036854776000 | Both 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. |
| size_is_big | BOOLEAN | true | When ON, size parameter represents the bigger image side. When OFF, it specifies the smaller one. |
| landscape | BOOLEAN | true | Specifies image orientation: When ON, width is bigger (image is horizontal). When OFF, height is bigger (image is vertical). |
| aspect_a | FLOAT | 16 | Two 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_b | FLOAT | 9 | Two 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. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| width | INT | — |
| height | INT | — |