Exit ComfyUI
The node that makes ComfyUI clock out for you
- any
This node is a kill switch. Drop it at the end of a graph and it waits a few seconds, then terminates your ComfyUI process - no confirmation, no "are you sure", the server is just gone. The author's stated reason for building it is Google Colab: run a mass-generation batch unattended, and once the last image saves, exit instead of letting a paid runtime sit idle for hours. If you've ever queued a big batch before bed and woken up to a still-spinning GPU, you know exactly why this exists.
You'd reach for it when the work is fully self-contained: a Colab notebook, a scheduled overnight run, a render farm-style queue where the machine's only job is to finish and free itself. It's a terminal node in the strictest sense - it has no outputs, takes a dummy input, and its entire contribution happens after everything upstream finishes. If you're running a long multi-item queue and want a smarter shutdown that respects it, the same pack has the "Exit when Last Batch" node. This one is the blunt instrument, and it's honest about it.
How it works
When the node runs it spawns a background thread that prints a countdown - "Exit ComfyUI in 5 seconds..." down to zero - then calls os._exit(0). That's not sys.exit and it's not a graceful shutdown. os._exit(0) terminates the process immediately, skipping Python's usual cleanup. No flushing of pending saves, no running finally blocks, no "did you mean it?" It's the difference between clicking "Shut Down" and holding the power button. For its purpose - stopping an unattended Colab runtime - that bluntness is exactly what you want.
The countdown also means the graph finishes first. Because the exit is deferred by wait_seconds, the current execution completes and the image hits disk before the process dies. The author set the default to 5 seconds, which is usually enough for a save to land.
The two inputs, that's it
any- a dummy input of any type. Wire it to the output of your final real node (e.g. Save Image). The node is an output node, so it runs every execution regardless, but connecting it forces it to run after the work is actually done rather than whenever ComfyUI happens to schedule it.wait_seconds(INT, default 5) - how long before the process is killed. Bump it if your last node needs more time to write files.
There are no outputs. It's a sink.
The trap nobody mentions
It's a timer, not a queue watcher. It never looks at ComfyUI's queue, so if ten more batches are pending when this node runs, the process dies on schedule and takes the remaining queue with it. That's fine for the single big batch on Colab it was built for; it's a data-loss footgun on a long unattended queue. If that's your scenario, use the pack's other node, which polls /queue and only exits once it's truly empty.
The Colab gotcha is worth stating too: exiting the process doesn't tear down the runtime. The README says it plainly - you still have to disconnect and delete the runtime on the Notebook side to stop paying.
Installing
Standard custom-node fare, no models to download and no heavy deps - the only requirement is requests, which ComfyUI effectively already ships. Install via ComfyUI Manager (search "ComfyUI-exit") or:
cd ComfyUI/custom_nodes
git clone https://github.com/watarika/ComfyUI-exit
Then restart ComfyUI. It's a small, low-traffic pack by a Japanese dev (the README is bilingual), v1.2.0 as of late 2025 - don't expect a huge community around it, but the code is simple enough to eyeball before trusting it, which you should do with anything that runs arbitrary shutdown logic.
Troubleshooting
- Server "crashes" and comes back. If you run ComfyUI under a supervisor, Docker restart policy, or a daemon that auto-restarts, the exit looks like a crash and the process may just spin right back up. That's not the node failing - that's your harness refusing to let it die.
- It exits but images are missing.
os._exitskips cleanup. If your save node writes slowly (big PNGs, remote drives), raisewait_seconds. - It fires before generation is done. Make sure
anyis wired to the last real node's output, or the node may execute early in the run.
If you want a softer shutdown path, that's what the pack's other node gives you via hard_exit=False - this one always hard-exits, by design.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| any | * | — | |
| wait_seconds | INT | 5 | — |
Outputs (0)
No outputs