ComfyUI Node

One-Shot Relay

The pass-through node that lets ComfyUI finally release your RAM

By redstonewhite·Created 5 months ago·Updated 5 months ago· 2
One-Shot Relay
  • value
  • value

ComfyUI holds onto every node's output for the whole run. That's usually a feature - it's why you can nudge a KSampler seed and the VAE decode doesn't re-run. But when one of your intermediates is a high-res latent or a stack of video frames, "holding on to it" means gigabytes of RAM and VRAM sitting idle while the pipeline limps onward. People reach for "clear cache" buttons, restart their instances mid-run, and dedicate whole threads to Wan 2.2 grinding to a halt on the second generation because ComfyUI never let go.

That's the problem this entire pack exists to solve, and One-Shot Relay is the supporting cast. The star is a right-click toggle, "Discard Output After Use", that marks any node so its output is freed the moment every downstream consumer is done with it - instead of living in the persistent cache. The relay is the trick for when that alone isn't enough.

What the relay actually does

It's a pass-through. One input, value, one output, value, and the type is * - wildcard, so it swallows anything: tensors, images, strings, audio, whatever. Wire something in, the identical thing comes out the other side. By itself it's the most boring node on the canvas.

It earns its keep through timing. Here's the subtlety: a discard-marked node's output is freed only after all of its downstream consumers have run. If a node produces a heavy output (a big image) and a light one (metadata, audio, a path string) that gets consumed by something way down the line, the heavy data stays stuck in the execution cache the whole run - the producer never fully "finishes." Route that light output through the relay instead, and the relay is its own node that completes right after the producer. Now the producer's consumers are all done early, its heavy output gets released, and the small value keeps riding safely through the relay to its late consumer. That's the "decoupling" the pack's README describes: the heavy stuff is freed sooner, the small stuff is retained for later.

In practice you'd grab it when a discard node has a mixed fan-out and you can watch the big branch finish long before the small one. It also doubles as a generic type-agnostic pass-through if you just want a clean split in a messy graph.

Installing it - the real story

This one isn't a ComfyUI Manager one-click, and that's the honest headline. The pack needs a small patch to ComfyUI's own execution engine - comfy_execution/graph.py and execution.py, a few lines each - to intercept the cache write-back. You clone it:

cd ComfyUI/custom_nodes
git clone https://github.com/redstonewhite/ComfyUI-OneShotOutputs.git

Then follow the README's patch instructions for those two core files. There are no pip dependencies and no models to download - the whole pack is one node class plus a frontend script. ComfyUI Manager may find the repo, but Manager installs custom nodes; it won't apply a patch to ComfyUI's own core files for you.

Where people get burned

The patch is the trap. Every time you update ComfyUI - and it updates constantly - git pull overwrites those two core files and your patch silently vanishes. The node stays in the menu; it just stops freeing anything, because the backend hook is gone. Re-apply the patches after every update, and sanity-check once that a marked node actually drops memory.

The other gotcha is the trade-off baked into the design: a discard-marked node always re-executes, because its output is never cached. Toggle it on a node you tweak and re-run a lot and you pay full recompute every time. That's intended behavior - mark the one-shot heavy hitters, not the things you iterate on.

And if you'd rather just nuke the whole cache and skip selectivity entirely, ComfyUI's own --cache-none flag already does that globally. This pack exists for the middle ground: keep most caching intact, release only the few monsters.

Categoryutils

Inputs (1)

NameTypeDefaultDescription
value*

Outputs (1)

NameTypeDescription
value*