Save Intermediate Steps (Advanced)
Don't save all 30 steps — this variant lets you pick the ones that matter
- model
- model
The plain SaveIntermediateSteps saves a preview every single step, which is what you want for a live progress stream - and a bit wasteful for a timelapse. The "Advanced" variant is the same node with three filters bolted on: save_every_n, start_step, and end_step. Same wrapper, same progress.json, same output, same install - but you control exactly which frames land on disk.
If you're making a timelapse of a 30-step Flux render, do you really need 30 frames where the first six are gray noise? No. Save every 3rd step between step 5 and 25 and you've got a tighter, smaller video with the same "it slowly came into focus" story. That's the whole point of this node.
How it works
Identical mechanism to the base node: it takes a MODEL, clones it, patches apply_model, and decodes a TAESD preview after each denoising step. The difference is a filter before anything gets written:
should_save = (current_step >= start_step and
current_step <= end_step and
(current_step - start_step) % save_every_n == 0)
Three required inputs now - model and steps as before, plus save_every_n (save every Nth step, default 1). The optional filters are start_step (default 0) and end_step (default 999). Note the counting: the step counter starts at 0, so the first denoise call is step 0, not step 1. If you want to skip the opening noise, set start_step to 5 and save_every_n to 3 - you'll get steps 5, 8, 11, and so on.
Everything else matches the base node byte for byte: job_id, output_folder, filename_prefix, format (jpeg default, png optional), include_base64 for base64 progress payloads, and a single model output that wires into your sampler. Flow models (Flux and friends) and epsilon-prediction models (SD 1.5, SDXL) are both handled.
Install and gotchas
Same install as the base node - ComfyUI Manager, search "ComfyUI-SaveIntermediates", or:
cd ComfyUI/custom_nodes
git clone https://github.com/DanielBartolic/ComfyUI-SaveIntermediates.git
Restart, done. No dependencies, no model files, MIT license.
The gotchas carry over too, so don't skip the base node's article. The big one: status in progress.json never flips to "completed" (the finalize() method is defined but never called), so your frontend should poll on progress_percent hitting 100 rather than on the status string. And end_step defaults to 999 with steps capped at 1000, so you can't accidentally cut off the tail unless you set it - if you want the last few frames, remember the default covers you.
One extra thing this variant does better than the base node: because it writes fewer files, it also writes less junk to disk. On long or batched generations that's a real difference, and the save_every_n knob is also a lazy man's way to keep your progress JSON from bloating with base64 if you've left include_base64 on. In practice, though: base node for streaming a progress bar, this one for anything you'll turn into a video or actually keep.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| steps | INT | 201–1000 | — |
| save_every_n | INT | 11–100 | — |
| job_idopt | STRING | — | |
| output_folderopt | STRING | progress | — |
| filename_prefixopt | STRING | step | — |
| formatopt | COMBO | jpeg | 2 options: jpeg, png |
| include_base64opt | BOOLEAN | false | — |
| start_stepopt | INT | 00–1000 | — |
| end_stepopt | INT | 9990–1000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| model | MODEL | — |