Bobs Latent Optimizer
One node to size your latent and hand your upscaler sane tiles
- latent
- tile_width
- tile_height
- upscale_by
- width
- height
If you've ever typed "1344" into a width box, cross-checked it against a trained aspect-ratio table, then manually divided by 8 to feed a tiled upscaler - this node is that math, packaged. BobsLatentNode (the standard variant of Bobs_Latent_Optimizer) takes an aspect ratio and a megapixel target, hands you a correctly-shaped empty latent, and also computes the tile dimensions you'd otherwise guess for a downstream tiled upscaler. It doesn't call any API, needs no key, and downloads no models. It's just geometry, done right.
The name slightly oversells it: it doesn't "optimize" a latent in the neural sense. It allocates a fresh empty latent and picks dimensions that are legal for the model you're about to run. That's the part people burn time on, because the rules differ per family - FLUX wants multiples of 64, SDXL has a set of trained ratios around 1024×1024, and video models carry extra constraints. This node bakes those rules in.
How it works
You give it an aspect_ratio (it accepts 1:1, 16:9, 3:2, or decimal forms like 1.5:1) and an mp_size dropdown - 10 presets from 0.25 up to 4, where 1 is a 1024×1024 area and 4 is 2048×2048. It computes the pixel width and height that cover roughly that area at that ratio, then rounds them to the alignment step for your model_type. From there it allocates a zeroed latent tensor with the right channel count for that family - 16 channels for FLUX, 4 for SDXL-style models - and the right VAE downscale, so the pixel dimensions you set actually describe the tensor you get.
The trickier half is the tiling math. upscale_by is not an upscale - the node never touches your image. It's used to estimate the final pixel output size (base × upscale_by), then the node picks tile dimensions for the tiled upscaler you'll run after VAE decode. It aims for a 2×2 grid of tiles, and only adds tiles (3×2, 2×3, 3×3…) when a single tile would exceed the 2048×2048 limit. Tile sizes are rounded up to a multiple of 8, which the tiled upscaler nodes expect.
The inputs that matter
aspect_ratio- the shape of the base image. Common values like16:9work as-is.mp_size- the "how big" dial.1(1024×1024) is the default and the one you'll reach for most; jump to1.5–2for higher-res first passes.upscale_by- feed it the scale factor you plan to use downstream (default 2). This drives the tile math only.model_type- pick your family: FLUX, SDXL, SD3, QWEN, or WAN. FLUX is default.batch_size- how many latents to stack, if you're generating a batch.
Outputs
Four outputs: latent (the empty latent, wire it straight into your KSampler), tile_width and tile_height (feed these into Ultimate SD Upscale, a tiled VAE decode, or similar after your first pass), and upscale_by passed through so a scale-expecting upscaler can grab it. The latent goes forward into sampling; the tile outputs sit in your back pocket for the upscale stage.
Installing it
Easiest via ComfyUI Manager - search for Bobs_Latent_Optimizer and hit install. Or the manual route:
cd ComfyUI/custom_nodes/
git clone https://github.com/BobsBlazed/Bobs_Latent_Optimizer.git
Restart ComfyUI. That's the whole install: this pack has zero Python dependencies and no model files - torch comes from ComfyUI itself, so there's nothing to fight over. Both nodes land in the latent/generate category.
Where people get burned
- Thinking
upscale_byactually upscales. It won't - nothing comes out bigger than the base resolution you asked for. It only computes tiles for the upscaler you add later. - Pushing
mp_sizetoo high. A4MP (2048×2048) FLUX latent is a big first pass on its own; the tile sizes only help the upscale stage, not the base generation. The node will warn in the log if a target can't be honored without distorting your aspect ratio. - Not restarting after install. It's the classic. Clone, restart, then look under
latent/generate.
The built-in EmptyLatentImage handles this job for one model at a time. If you hop between FLUX, SDXL, and WAN in one workflow folder, this node removes a whole category of "why is my latent 16 channels" confusion - and it's free to try.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| aspect_ratio | STRING | 1:1 | Aspect ratio of the base image, e.g. '1:1', '16:9', '3:2'. |
| mp_size | COMBO | 1 | Approximate megapixel area of the base image. Values map to common standard resolution areas (1 = 1024x1024, 4 = 2048x2048). |
| upscale_by | FLOAT | 2.001–10 | Upscale factor for the FINAL output image. Used only to compute the tile dimensions; the generated latent is NOT upscaled. |
| model_type | COMBO | FLUX | Model family. Sets latent channels, VAE downscale and pixel alignment. Video families (WAN, WAN22, HUNYUAN_VIDEO, HUNYUAN_VIDEO_15, COSMOS, COGVIDEOX, MOCHI, LTXV, SEEDVR2, HUNYUAN_IMAGE_REFINER) produce a 5-D latent and use the `length` input. See the README for the full table. |
| batch_size | INT | 11–64 | Number of latents in the batch. |
| max_tile_sizeopt | INT | 2048256–8192 | Largest tile edge allowed before the tile grid is subdivided further. Lower this if your upscaler runs out of VRAM. |
| lengthopt | INT | 11–4096 | Number of video frames. Only used by video model families; ignored (with a warning) for image models. |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | Empty latent batch sized for the selected model. |
| tile_width | INT | Suggested tile width for a tiled upscaler operating on the upscaled pixel output. |
| tile_height | INT | Suggested tile height for a tiled upscaler operating on the upscaled pixel output. |
| upscale_by | FLOAT | The upscale factor, passed through unchanged for convenience. |
| width | INT | Base image width in pixels. |
| height | INT | Base image height in pixels. |