ComfyUI Node

Cache any

Skip the slow part when nothing changed

By lokinou·Created 11 months ago·Updated 8 months ago· 2
Cache any
  • any_to_cache
  • any_key
  • any_cached
  • key_passthrough
cache_nameoutput
cleanup_on_mismatchtrue
force_recreatefalse

Every ComfyUI power user eventually hits the same wall: you've got a workflow where one stage takes two minutes - a controlnet preprocess, a first-pass sample, an upscaler - and you're iterating on the other half. Re-running the whole graph every time is maddening. Cache any is the node that remembers: it saves whatever you feed it to disk keyed by a name-plus-hash, and on the next run, if the key matches, it hands the saved value back and skips evaluating the upstream branch entirely.

That last bit is the magic, and it's why this node exists instead of you just writing pickle files yourself. ComfyUI's lazy-input mechanism means the expensive nodes feeding any_to_cache simply don't execute on a cache hit - you get the cached result without the wait, like a memoized function in the middle of your graph. It's the closest thing ComfyUI has to an incremental build.

How it works

The node keeps its cache as .pkl files in ComfyUI/output/cached_outputs/. The filename encodes both the cache name and an MD5 of the key: myname+<hash>.pkl. On each run it checks:

  • Cache file exists and force_recreate is off → hit: load the pickled value, return it, and tell ComfyUI not to bother evaluating any_to_cache.
  • No matching file, or force_recreatemiss: request the upstream value, pickle it to disk, return it.

By default it also does cleanup: on a miss it deletes other files with the same cache name but a different hash, so old versions don't pile up. The README flags that cleanup as "todo: fix it" - and indeed, a sloppy globbing edge case with + in names is the kind of thing to keep in mind (see gotchas).

Inputs and outputs

  • any_to_cache (required, any) - the expensive thing you want saved.
  • any_key (required, any) - the fingerprint that decides hit vs. miss. This is where any to hash (or any to hash x2) earns its keep: wire a hash here and the key is "image + prompt," not just one field. The README explicitly suggests combining them for multiple-input keys.
  • cache_name (string, default "output") - the human-readable namespace. Give it a real name or every cache collides.
  • cleanup_on_mismatch (bool, default on) - whether stale cache files for this name get deleted.
  • force_recreate (bool, default off) - ignore the cache and recompute, useful when you know the inputs changed in a way the hash can't see.

Outputs are any_cached (the value, from cache or fresh) and key_passthrough (your key, unchanged, for wiring further).

Gotchas - read this before trusting it

  • Hash reliability. The README is upfront: tensor-typed objects produce unreliable hashes. Images got a fix, but conditioning-type tensors are still dicey - the same conditioning can hash differently between runs, so cache keys built from them can miss when they should hit. If your cached branch is downstream of heavy conditioning math, verify it's actually hitting before you rely on it.
  • + is forbidden in cache_name, and it must be a non-empty string. None keys raise.
  • It's pickled data. Fine for your own outputs; don't point it at anything untrusted.
  • Caches live in your output folder, so clearing outputs wipes your cache. That's by design, but it surprises people.

Install

Part of lokinou/comfyui-better-flow - install the pack once and all seven nodes appear. ComfyUI Manager: search "comfyui-better-flow". Or:

cd ComfyUI/custom_nodes
git clone https://github.com/lokinou/comfyui-better-flow.git

Restart ComfyUI fully afterwards. No pip install, no model downloads - the pack is dependency-free.

Categoryworkflow

Inputs (5)

NameTypeDefaultDescription
any_to_cache*
any_key*
cache_nameSTRINGoutput
cleanup_on_mismatchBOOLEANtrue
force_recreateBOOLEANfalse

Outputs (2)

NameTypeDescription
any_cached*
key_passthrough*