Save WebP (Timestamp)
Small files that remember how they were made
- images
ComfyUI's default SaveImage writes a big PNG with the entire workflow stuffed into it as text chunks. That's the ecosystem's best idea - drag the file back onto the canvas and the graph rebuilds - and it's also why output/ fills a disk in a weekend.
This node is the other end of the tradeoff: WebP, timestamped filenames that can never overwrite each other, and the parts of the metadata that matter written into EXIF plus a sidecar JSON. Smaller files, and you can still get your prompt and seeds back. What you lose is the graph.
What it writes
Filenames are YYYYMMDD_HHMMSS_millis_index.webp, e.g. 20261005_142233_918_000.webp. One timestamp is taken per batch and the index counts through the batch, so two images saved in the same millisecond can't collide - the "no overwrites" claim is real, and it's a small detail that other timestamp savers get wrong.
The widgets:
images- your IMAGE input.quality(90) andlossless(false). Lossless ignores quality entirely (Pillow would warn about it and then ignore it anyway, so the node skips passing it).subdir(defaultwebp_outputs) - a folder underoutput/. It's sanitised: absolute paths and..are rejected and fall back to the default, and only safe characters survive, so a weird string can't write outside your output directory.embed_metadata(true) - writes a JSON summary into the EXIFImageDescriptiontag (270): node name, timestamp, positive prompt, negative prompt, seeds.save_json(true) - writes a sidecar.jsonnext to each image with the summary plus the full prompt and workflow.
It's an output node with no outputs, so it fires on every run.
Positive and negative are resolved by tracing the workflow's links back from the sampler, falling back to positional order if that fails; seeds are collected from seed and noise_seed inputs. The sidecar's copy of the prompt dict is passed through a secret redactor - credentials are stripped before it hits disk. The workflow copy can't be: ComfyUI stores widget values as a positional array with no field names, so there is nothing to scrub by name.
The thing to understand before you adopt it
WebP re-encodes by definition, and it has no PNG text chunks, so the node graph does not travel with the file. ComfyUI's drag-to-restore understands PNG and only PNG. This is an archive and gallery format; it is not how you hand someone a reusable workflow.
That's not a flaw in the node, it's the container. The honest framing: PNG is the master, WebP is a derivative. If a generation matters, keep the PNG. If you're pumping out hundreds of iterations and mostly need the prompt back later, this is a much better deal than a pile of 8 MB PNGs - pair it with Load WebP Info and you can still recover the positive prompt, negative prompt and seeds.
Three related traps: EXIF's chunk has a size budget, so an oversized summary is truncated at 60,000 characters (the full text survives in the sidecar); turn save_json off and EXIF becomes your only copy; turn embed_metadata off and there's nothing to recover at all. Workflows pinned to an old value pick up whatever the current default is, which is true of any ComfyUI node but bites harder when the widget controls whether metadata exists.
Install
ComfyUI Manager → ComfyUI-FeiFei, or:
cd ComfyUI/custom_nodes
git clone https://github.com/aifeifei798/ComfyUI-FeiFei.git
# restart ComfyUI; Save WebP and Load WebP Info show up under FeiFei
Pillow and numpy, both already in ComfyUI. No models. Check that both WebP nodes appear - they live in the same module, and each node group in this pack loads inside its own try/except, so a failure prints a [FeiFei] SaveWebPWithTimestamp failed to load: line in the console with the traceback beneath it.
When to reach for it
- Big iteration runs you'll want to revisit. Small files, timestamped, prompts recoverable.
- Posting to a gallery. WebP is what most platforms re-serve anyway, and the EXIF travels further than a PNG text chunk survives.
- Anything you'd call a final image - keep the PNG, or use the pack's Watermark node and then save both.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| quality | INT | 901–100 | — |
| lossless | BOOLEAN | false | — |
| subdir | STRING | webp_outputs | — |
| embed_metadata | BOOLEAN | true | — |
| save_json | BOOLEAN | true | — |
Outputs (0)
No outputs