Why ComfyUI Recomputes Only What Changed

A repeated ComfyUI workflow does not have to begin from an empty runtime every time. This chapter examines how the system decides whether a node's earlier result still matches the current graph, and how that decision leads to a full cache hit, selective recomputation, or a deliberate eviction. The practical goal is diagnosis: the reader should be able to predict why an unchanged branch is reused, why a changed node affects its descendants, and why a custom node that hides external state can make reuse unsafe.

A cache key is an argument about identity

Caching is often described as “remember the output.” ComfyUI needs a stronger question: under what conditions is this output the result of the same computation? A node's visible widget values are only part of the answer. A node may consume a linked value from another node, and that upstream value may itself depend on a long chain of ancestors. A file loader may point to the same filename while the file's contents have changed. A node may also be non-idempotent, meaning that repeating the same declared inputs at a different identity should not automatically reuse another node's result.

ComfyUI builds its output-cache identity from these relationships. For each node, the input-signature cache records the node's class type and a change fingerprint, then incorporates literal inputs and an ordered representation of linked ancestry. A link is represented by which ancestor it came from and which output slot it selects. The ordering is deterministic, so the signature reflects the shape of the dependency path rather than depending on how a dictionary happened to be traversed. Values are converted into hashable structures where the cache can safely do so; unsupported objects are treated as unhashable rather than silently declared equivalent.

The change fingerprint is an explicit opportunity for a node to say that its external input has changed. The older node interface calls this hook IS_CHANGED; the newer interface calls the corresponding hook fingerprint_inputs. If a node has neither, its ordinary declared inputs and linked ancestry provide the available identity. If it has a fingerprint, the returned value becomes part of the change decision. A file loader is a clear example: it hashes the contents of the referenced file with SHA-256, so a modified image or latent file is not treated as the same input merely because its name stayed constant.

This makes the cache different from a screenshot archive. It does not ask whether two outputs look alike. It asks whether the current node and its dependency context match a prior execution record. A changed seed is a changed literal. A changed sampler setting is a changed literal. A changed upstream conditioning result changes the ancestry signature of the node that consumes it. A changed image file changes the loader's fingerprint. Each difference gives the runtime evidence that an old result should not be trusted for the current graph.

Node identity can matter too. The cache can include a node identifier when a node is marked non-idempotent or when the node's contract uses its unique identifier. This prevents a result that is safe to reuse only for one graph identity from being transferred to another node just because their visible inputs look alike. The choice is conservative: reuse is valuable only when the system has a reasonable basis for believing that the prior output means the same thing now.

There are several layers of cached state. The output cache stores a node's results and associated UI information.