Nodes/comfyuitools/Upload Image to remote
ComfyUI Node

Upload Image to remote

The node that makes 'generate here, img2img over there' real

By xxxususu·Created 2 months ago·Updated 2 months ago· 0
Upload Image to remote
  • images
  • filename
  • remote_apply
remote_urlhttp://127.0.0.1:8288/
target_nodeid
target_paramimage
filename_prefixnetdist_relay

You've got a second GPU. It could be a spare 3060 in the same tower, a PC on the same Wi-Fi, a machine you SSH into at 1am. ComfyUI doesn't natively spread one workflow across machines; this pack exists to fill exactly that gap. UploadImageToRemote is the piece that hands a finished local image to that other ComfyUI so its workflow can do img2img, upscale, or img2video on it and hand something back. Think of it as the forwarding slip in a relay race: generate on box A, toss the PNG to box B, let B do the second pass. Not for everyone - but if you've watched a 4090 idle while your UNet pegs a 3080, you're the target audience.

The name undersells the mechanism. There's no custom server, no API key, no daemon on the far end. The node takes your IMAGE, encodes it to PNG, and POSTs it to ComfyUI's native /upload/image endpoint (type=input, overwrite=true) - the same endpoint the web UI uses when you drag a file in. That means the remote machine just needs to be a normal ComfyUI running with --listen. It writes into the remote's input folder, so a plain LoadImage node there can pick it up. Your second box doesn't even know the pack is installed.

The clever part is the output. Besides a filename string, it returns a remote_apply (type REMOTEAPPLY) - a little bundle of (target_nodeid, target_param, value, type) that plugs straight into this pack's RemoteChainStart or RemoteQueueSimple nodes. Those dispatch the remote workflow and swap the target LoadImage's image input to the just-uploaded filename. That's the whole relay: upload → rewrite one JSON field → queue on remote → FetchRemote polls /history and pulls the result back.

The inputs that actually matter

Four of the five inputs you'll set once and forget. The one beginners fumble is target_nodeid - it's the ID of the LoadImage node in the remote workflow's API-format JSON, not anything visible on the graph. Export the remote workflow as API JSON (dev mode → "Save (API Format)"), find the entry whose class_type is LoadImage, and its top-level key is the ID. Plug that in, leave target_param at its default image, and set remote_url to the remote box (http://192.168.x.x:8188/, not 127.0.0.1 unless it's the same machine). filename_prefix defaults to netdist_relay and the remote overwrites it each run, so you won't accumulate junk in its input folder.

One honest limitation from the source: only the first image of a batch is uploaded, because a single LoadImage consumes a single file. Batched relay isn't supported yet, and the author admits it. Don't build your pipeline on it.

Install and wiring

The pack is a fork of a fork: xxxususu/comfyuitools (this repo) is a fork of ComfyUI_NetDist Plus, which was itself a fork of City96's ComfyUI_NetDist. Only the upload node is new here. Install it once, on the controlling machine - the remote stays vanilla ComfyUI.

cd ComfyUI/custom_nodes
git clone https://github.com/xxxususu/comfyuitools
pip install requests   # the only dependency; requirements.txt just wants requests>=2.28.2

ComfyUI Manager also finds it if you search the pack title. Then, on the remote: start it with --listen so your controller can reach it. Load the remote workflow's API JSON locally with the pack's Load workflow (disk) node (copy the JSON into your ComfyUI/input/ folder first), and chain: UploadImageToRemoteRemoteChainStartRemoteQueueWorkerFetchRemote → local SaveImage.

The traps that will bite

  • RemoteQueueWorker's outputs must be any, not final_image. With the default it strips the remote's PreviewImage/SaveImage nodes, which assumes the remote uses a FetchRemote node. Almost nobody does on a hand-built workflow. any keeps the outputs intact.
  • FetchRemote only runs if its output feeds a local SaveImage/PreviewImage. The whole chain executes off image dependencies, so if the fetch result dead-ends, nothing happens and you get no preview.
  • Nothing triggers. If you changed a sampler setting but not the seed, the upload node may be considered "unchanged" and skip. Set the chain's trigger to always (the README's own advice).
  • 16-second timeout on the upload request - a giant PNG over slow Wi-Fi can trip it. It's one POST; this is not built for 4K video frames.

Be aware of what you're signing up for: this is a lightly-maintained hobby pack ("I am a primitive coder," says the README, credit to Claude for debugging), and the README still tells you to clone the upstream NetDist repo in its install section - trust the repo you're on, not the stale copy-paste. Community reports on the NetDist lineage are mixed-to-good: real 15–20% speedups from a second card, and plenty of people who found it more fiddling than it was worth. If you have a spare box that's always on, this is the cheapest way to give it a job.

Categoryremote/image

Inputs (5)

NameTypeDefaultDescription
imagesIMAGE
remote_urlSTRINGhttp://127.0.0.1:8288/
target_nodeidSTRING
target_paramSTRINGimage
filename_prefixSTRINGnetdist_relay

Outputs (2)

NameTypeDescription
filenameSTRING
remote_applyREMOTEAPPLY