Nodes/ComfyUI-SaveIntermediates/Save Intermediate Steps
ComfyUI Node

Save Intermediate Steps

Stream every sampling step to your frontend

By workordie·Created 8 months ago·Updated 8 months ago· 0
Save Intermediate Steps
  • model
  • model
steps20
job_id
output_folderprogress
filename_prefixstep
formatjpeg
include_base64false

If you've ever built a web frontend around ComfyUI, you know the drill: user hits "generate", and your UI shows a loading spinner for 30 seconds. This node fixes that specific pain. SaveIntermediateSteps wraps your model, saves a preview image after every sampling step, and writes a progress.json your frontend can poll - step number, percent, and the latest image, plus an optional base64 version if you don't want to deal with serving files. It's the closest thing ComfyUI has to A1111's "save intermediate images" extension, which people have been asking for since 2022.

It's MIT-licensed, has zero extra dependencies, and needs no model downloads. You can't ask for a much better first custom node.

How it actually works

The node doesn't sit between the sampler and the VAE like you might expect. It wraps the model: you take the MODEL from your checkpoint/UNET loader, pass it through this node, and feed the output into your sampler instead. Under the hood it clones the model and monkey-patches its apply_model method, so after every denoising step it reconstructs what the image should look like at that point (the "denoised" x0 estimate) and decodes it.

That decode is the clever part: it uses ComfyUI's own built-in latent_preview module, which is TAESD-based. So no VAE decode, no memory spike, no extra model files - these are the same cheap little previews ComfyUI already shows in its preview panel, just persisted to disk. The code handles both prediction styles, so it works across the model divide the community keeps tripping on: epsilon-prediction models (SD 1.5, SDXL) use x0 = x - sigma·eps, and flow-matching models like Flux use the model's own denoised calculation. That flow support was added in a Jan 2026 update, and it matters - this is one of the few intermediate-step savers that doesn't assume you're on SDXL.

What you actually set

Only two inputs are required, and one of them is trivial:

  • model - from your checkpoint loader, into your sampler. Required, obviously.
  • steps - your total sampling steps, used purely for the progress math in progress.json. Set it to whatever your KSampler uses.

The optional ones are the fun part:

  • job_id - an ID for this run. It becomes the folder name under output/progress/, so the same run can be found by a later node or polled by your frontend. Leave it blank and the node generates a timestamp folder instead.
  • output_folder / filename_prefix - base folder name (default progress) and file prefix (default step).
  • format - jpeg (default, quality 85) or png.
  • include_base64 - set this if you want progress.json to carry the latest frame as a base64 string instead of you serving image files.

Output: a single model wire that goes into your sampler. That's the whole graph:

Load Checkpoint → [Save Intermediate Steps] → KSampler → ...

Installation

ComfyUI Manager is the easy path - search for "ComfyUI-SaveIntermediates" and hit install. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/DanielBartolic/ComfyUI-SaveIntermediates.git

Then restart ComfyUI. That's it - the repo has no requirements.txt and pulls nothing extra; it leans on ComfyUI's bundled latent_preview (TAESD) and the Python standard library.

Where people get burned

Two things, both grounded in the actual code. First, the README's polling example checks for status === 'completed' - but the finalize() method that writes that status is never called. Your progress.json will say "generating" right up until the end. Poll on progress_percent === 100 (or just detect a stable file list) instead, or your frontend will spin forever.

Second, set expectations about image quality: these are TAESD previews, small and a little soft, not full-res VAE decodes. Great for progress bars and timelapses, wrong tool if you need pixel-accurate frames - that's what the VAE is for. And if you're generating video latents, the node only saves the first frame of each step. Fine for showing "it's working", not a frame-accurate video preview.

Categorysampling/streaming

Inputs (7)

NameTypeDefaultDescription
modelMODEL
stepsINT201–1000
job_idoptSTRING
output_folderoptSTRINGprogress
filename_prefixoptSTRINGstep
formatoptCOMBOjpeg2 options: jpeg, png
include_base64optBOOLEANfalse

Outputs (1)

NameTypeDescription
modelMODEL