Nodes/CubicJ Comfy Nodes/Force Full Unload (VRAM+Pinned)
ComfyUI Node

Force Full Unload (VRAM+Pinned)

When ComfyUI won't let go of VRAM, hit it with Force Full Unload

By cubicj·Created 4 months ago·Updated 3 months ago· 0
Force Full Unload (VRAM+Pinned)
  • passthrough
  • passthrough
verbosetrue
release_pinned_ramtrue
aimdo_analyzetrue

ComfyUI is a hoarder. It keeps every model you've loaded sitting in VRAM so the next run is instant, and it pins memory in RAM so it can swap things fast without a trip to the disk. That's great for iterating on one workflow and miserable when you switch between heavy models - nothing unloads, the 22GB text encoder from your LTX-2 gen is still parked on the card, and your next run dies with an OOM error that makes no sense. Force Full Unload is the sledgehammer for exactly that situation.

The name is accurate. This node doesn't politely ask ComfyUI to free a bit of cache; it takes everything it can find and throws it out. It's a passthrough node, meaning you wire something in and get the same thing back out - the point isn't the data, it's the side effect of running it.

How it works

Read the source and you'll see it's a careful, deliberate memory nuke, not a random torch.cuda.empty_cache(). In order, it:

  1. Snapshots VRAM usage (and logs it, if verbose is on).
  2. Resets cast buffers and synchronizes the CUDA stream.
  3. Calls unload_all_models() - the same thing ComfyUI does when you hit the unload button.
  4. For any model that's partially offloaded to RAM, force-releases the dynamic buffers it's holding - the partially_unload / dynamic_vbars machinery that normal unloading can leave behind.
  5. Unpins pinned memory from model modules, if your ComfyUI build has the pinned-memory subsystem.
  6. Clears the loaded-models list, runs the garbage collector three times, then does soft_empty_cache(), torch.cuda.empty_cache() and ipc_collect().
  7. Optionally asks NVIDIA's comfy_aimdo helper (if you have it installed) to analyze and clean up - and skips it gracefully if you don't.

What you're actually getting here is the difference between "VRAM is free" and "VRAM and pinned RAM are both free." Pinned memory is the bit most people forget: ComfyUI pins host RAM buffers so transfers to the GPU are fast, and on a system with limited RAM that pinned pool quietly eats your system memory even after the VRAM looks clean.

The inputs

  • passthrough (required, any type) - wire anything through it so the node sits in your graph. The value comes out unchanged.
  • verbose (default on) - prints a before/after VRAM + pinned + loaded-models breakdown to the console. Leave it on the first time; it's genuinely useful to see what was occupying the card.
  • release_pinned_ram (default on) - the pinned-memory cleanup. This is the part that makes it stronger than ComfyUI's built-in unload.
  • aimdo_analyze (default on) - the optional AimDo hook.

Because it's marked as an output node, ComfyUI always runs it regardless of caching. That's the feature: it fires every execution, not just when a cached value changes.

Installing it

Comes in the cubicj-comfy-nodes pack. Manager: search "CubicJ Comfy Nodes" and install. Manual:

cd ComfyUI/custom_nodes
git clone https://github.com/cubicj/cubicj-comfy-nodes
# restart ComfyUI

Zero dependencies. One thing worth knowing: it reaches into comfy.model_management and the optional comfy.pinned_memory module, so keep ComfyUI reasonably current - the pinned-memory cleanup silently skips on older builds.

Where to put it, and the trap

The natural spot is at the end of a workflow for a model you won't need again - say, the tail of an LTX-2 job before you jump back to image gen. The trap is the flip side: since it always runs, sticking it inside a workflow you re-run repeatedly forces a full reload every single time, and reloading is slower than keeping the model warm. Use it for the boundary between heavy tasks, not as a permanent resident in a workflow you hammer all day. If you only want to drop one model, unload_all_models is the blunt version; this is the version for when that wasn't enough and something is still squatting on the card.

Categorymemory

Inputs (4)

NameTypeDefaultDescription
passthrough*
verboseoptBOOLEANtrue
release_pinned_ramoptBOOLEANtrue
aimdo_analyzeoptBOOLEANtrue

Outputs (1)

NameTypeDescription
passthrough*