NBP RAM Cleanup
A node that actually hands system RAM back to the OS
- passthrough_image
- passthrough_image
Let's be real about what "RAM cleanup" nodes usually do: gc.collect(), a torch cache clear, and a console message that sounds like progress while your memory usage barely moves. NBP RAM Cleanup is not that node. It's an end-of-workflow utility that goes after the actual reasons ComfyUI's Python process slowly eats your system RAM on long runs - and it's aggressive enough that you should know what it's doing before you chain it into a production graph.
The problem it targets is real. ComfyUI keeps node-output caches around between runs, and they hold strong references to tensors - including model weights that got shuffled from VRAM back into system RAM. Run enough batches on a big workflow and you get the classic complaint from the community: "Over multiple batches, the memory allocated to Python creeps up until it has entirely consumed all of RAM available." That's system RAM, not VRAM, and it's why the standard advice (unload models, empty the torch cache) never fully fixes it - the references are still there.
What it actually does
Read the source and you'll find four targeted moves, in a deliberate order:
- Clears the
PromptExecutornode-output caches - it finds the live executor via Python's object graph and wipes the dicts that hold last-run tensor references. This is the part most "cleanup" nodes never touch. - Unloads models and drops every
current_loaded_modelsreference so GC can finally collect the tensors. Crucially, it does not callunload_all_models()first - the author's own note says doing so would move 8+ GB from VRAM to RAM right before measuring, making the numbers look worse. - Runs
gc.collect()twice. - Returns freed pages to the OS - via tcmalloc's
ReleaseFreeMemoryif you run with tcmallocLD_PRELOAD-ed (where libc'smalloc_trim(0)is a no-op), falling back tomalloc_trim(0)otherwise.
It reports before/after RAM figures in the console, which is where psutil comes in - the pack's requirements file pins it, but the node degrades gracefully without it (it still runs, just prints no numbers).
Inputs and output
There are none required. One optional passthrough_image input, one passthrough_image output of type IMAGE - its whole job is to let you chain the node inline without breaking the graph, since it's marked as an output node (it always runs, even with nothing connected downstream). In practice you just drop it at the end of the workflow; the passthrough is there if you want to keep a visual wire running past it.
Where it's great - and where to be careful
The right use is the long-horizon one: a batch run on a RAM-starved box, or a workflow you keep running in a loop where memory climbs until everything thrashes. Stuck at the end of that pipeline, NBP RAM Cleanup does the job more thoroughly than the usual suspects.
The caution is that it's a blunt instrument reaching into ComfyUI internals - it imports the execution module, walks gc.get_objects(), and clears caches whose shape can change between ComfyUI versions. If it breaks after an update, that's why. It also clears the node-output cache, so the next run may recompute things ComfyUI would otherwise have skipped, and it drops every loaded model - so the next item in your queue pays a reload. On a single-user box that's fine; on a shared server it'll make the next job slower.
Install
One of three nodes in INDG_CustomNodes - install the pack once via ComfyUI Manager (search "INDG_CustomNodes") or:
cd ComfyUI/custom_nodes
git clone https://github.com/SorenWeile/INDG_CustomNodes.git
then restart ComfyUI. No model downloads. Worth a footnote: the README says no dependencies beyond ComfyUI, but the repo's requirements.txt does pin psutil - install it if you want the before/after RAM readout; skip it and the node still works. And treat the pack for what it is: a single-commit, one-author toolset with no community track record yet, so give the code a glance if you're the paranoid type.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| passthrough_imageopt | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| passthrough_image | IMAGE | — |