Nodes/Model Phase Sync/Save Image (Atomic)
ComfyUI Node

Save Image (Atomic)

The Save Image for people whose scripts watch the output folder

By josetseph·Created 2 months ago·Updated 29 days ago· 1
Save Image (Atomic)
  • images
    filename_prefixComfyUI

    Stock Save Image is fine - unless something else is watching your output folder. A Discord bot, a file harvester, a cron that picks up new PNGs the moment they appear, a script that forwards finished images somewhere. Those tools have a nasty habit of catching files mid-write: stock Save Image opens the target file and writes into it in place, so a watcher can grab it while it's zero bytes or half-written, and now your pipeline has a corrupt PNG it will forever try to read.

    Save Image (Atomic) is the drop-in fix: same naming, same folder, same metadata - but the file is written to a temp sibling (.partial.<pid>) and moved into place with os.replace() only when the write is complete. The final filename appears on disk atomically. A watcher either sees nothing, or sees the finished file. Never a half-written one.

    That's the entire idea, and if nothing harvests your output folder you genuinely gain nothing - this is a node for people running ComfyUI as a stage in a bigger automated pipeline, not a quality knob. It ships in the Model Phase Sync pack because the pack's whole philosophy is checkpointing and atomic handoff between phases: same discipline as its Save Latent (Atomic) and Save Conditioning nodes, which exist so downstream processes never act on truncated data.

    How it works

    Mechanically it's the core Save Image writer with the rename swapped in: it embeds the prompt and any extra_pnginfo as PNG metadata (unless you run with --disable-metadata), uses the same counter-based filenames (prefix_00001_.png, incrementing per batch), honors subfolders in filename_prefix, and compresses at level 4 - the core default. The only real difference is that the bytes land in a temp file first and os.replace() promotes it.

    The inputs

    Only two, and both are the same as stock:

    • images (required, IMAGE) - the batch of images to save.
    • filename_prefix (required STRING, default "ComfyUI") - same convention as core Save Image: prefix and optional subfolder. outputs/out/ puts files in out/.

    No outputs - it's an output node (is_output_node: true), so ComfyUI always runs it and treats it as the end of a branch.

    Install

    This is one of five-ish nodes in Model Phase Sync. Via Manager search "Model Phase Sync", or:

    comfy node install model-phase-sync
    

    Manual:

    cd ComfyUI/custom_nodes
    git clone https://github.com/josetseph/ComfyUI-ModelPhaseSync.git
    

    Restart ComfyUI; it's under model_phase_sync. No Python dependencies, no downloads, MIT licensed.

    Gotchas

    • Don't expect different filenames than stock - if your watcher keys off the _00001_ pattern, it keeps working unchanged.
    • The atomic guarantee only covers the file appearing complete. If your watcher then reads it while it's complete, fine; if it watches for the filename before the bytes are there, it still works - that's the point.
    • There's a deliberate reason it lives here rather than in a save-focused pack: it's meant to be the terminal node of a barrier workflow where each branch lands independently and a downstream process collects results as they finish.
    Categorymodel_phase_sync

    Inputs (2)

    NameTypeDefaultDescription
    imagesIMAGE
    filename_prefixSTRINGComfyUI

    Outputs (0)

    No outputs