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

Save Latent (Atomic)

Checkpoint your latents before the batch can lose them

By josetseph·Created 2 months ago·Updated 30 days ago· 1
Save Latent (Atomic)
  • samples
  • samples
filename_prefixlatents/ComfyUI

Save Latent (Atomic) writes a LATENT to disk as a .latent file - compatible with core Load Latent and with this pack's Load Latent (Upload) - and finishes with an atomic rename. It looks like a tiny variation on stock Save Latent, but it earns its place for two reasons, and both are about not losing hours of sampling.

Reason one: crash safety inside a barrier batch. A Sync Barrier waits for every sampler to finish before any VAE decode runs. That's what stops the model thrash - and it also means no PNGs appear on disk until the whole sample phase is done. If ComfyUI crashes mid-batch, every finished branch existed only as in-memory latents. Gone. This node breaks that: Save Latent (Atomic) depends only on its own sampler, so it writes the moment that branch finishes, before the barrier lets anything else move. Crash now, and you keep every branch that got past its sampler. Use distinct prefixes per prompt (latents/zimage_01, latents/zimage_02…) so you can tell the branches apart later.

Reason two: phase-split pipelines. Sample in one workflow (KSampler → Save Latent), then decode in a later, separate workflow (Load Latent (Upload) → VAE Decode → Save Image). No resampling, and the decode graph never needs CLIP in memory. People build this shape manually all the time - saving latents to dodge a decode OOM after a long run is a familiar community pattern - this pack just makes the handoff clean and atomic.

How it works

It uses ComfyUI's own save_torch_file to write a safetensors with the latent_format_version_0 marker - the same format stock Save Latent writes - then os.replace()s a temp file into place so no watcher ever sees a truncated .latent. It embeds the prompt and extra_pnginfo as metadata unless you run --disable-metadata. Naming follows the standard counter scheme: prefix_00001_.latent.

It's also a passthrough: the same samples you put in come out the other side. That's deliberate - you can chain it before a barrier so each branch checkpoints itself and then still flows into the barrier. That's the pattern the pack's example workflows use.

The inputs

  • samples (required, LATENT) - the latent batch to checkpoint.
  • filename_prefix (required STRING, default "latents/ComfyUI") - note the default already includes the latents/ subfolder, which is where the matching loaders look.

One output, samples (LATENT), echoing the input through.

Install

Part of Model Phase Sync - 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; under model_phase_sync. No dependencies, no downloads, MIT.

Gotchas

  • Files land in output/latents/. The dropdowns in the loaders scan output/latents, input/latents, and input/, so if you're about to decode in another workflow, know which of the three it's in.
  • If you're checkpointing per-branch inside one batch, distinct prefixes are not optional - without them you can't map a latent back to its branch when the batch dies.
  • The passthrough is subtle: it's an output node (is_output_node: true), yet it also returns the latent. Wire it before a barrier and you get both the checkpoint and the ordering guarantee.
Categorymodel_phase_sync

Inputs (2)

NameTypeDefaultDescription
samplesLATENT
filename_prefixSTRINGlatents/ComfyUI

Outputs (1)

NameTypeDescription
samplesLATENT