Nodes/CMK Flow/CMK Boundary Cache
ComfyUI Node

CMK Boundary Cache

Why your side branch re-upscales the same image twice

By CMKFlow·Created 3 months ago·Updated a day ago· 6
CMK Boundary Cache
  • MODEL (opt)
  • IMAGE
  • LOG
  • diagnostic
  • MODEL
  • IMAGE
  • LOG
  • diagnostic

Four CMK nodes share the display name "CMK Boundary Cache" and this is one of them - the Upscale & Save variant. If you found it in a graph and can't tell which boundary you're looking at, the class name or the node's own console label (/ Upscale & Save) is the only reliable identifier. Functionally it is a cache checkpoint on a side branch.

Why it exists: an upscale-and-save branch hangs off your generation as a second consumer of the same image. ComfyUI's normal caching works backward from output nodes, and once a user adds a second output node - say the Visualizer plus a save branch - you get two runs of an expensive path over identical pixels. CMK's answer is a boundary node whose only job is to remember the decoded result so the branch that already ran doesn't run again.

How it works

The node is a subclass of the pack's FaceSwap boundary, re-scoped: _SCOPE = "upscale_save_boundary", schema cmk_upscale_save_boundary_v1, label "Upscale & Save". The three shared session dictionaries (_DETAILER_SESSION, _Z_IMAGE_SESSION, _FACE_REBUILD_SESSION) and the scope-specific disk store do the work.

The sequence is lazy-evaluation driven:

  1. check_lazy_status computes a cache key from the node's own identity and schema version - deliberately not from a recursive serialisation of the whole upstream graph. CMK's architecture doc is explicit that full-graph fingerprinting is forbidden here, because it turns a cache check into an exponential traversal.
  2. If the key is already present in the session dictionary and the disk artifacts exist, the node reports itself ready and never asks upstream for its inputs. That is the actual saving: the upscaler isn't evaluated at all.
  3. On a miss it materialises the inputs, writes the image and log under ComfyUI/temp/cmk/, parks the model pipe and diagnostic in the session dict, and prints MISS → STORED.
  4. Later runs in the same ComfyUI session print HIT and return the stored payload.

The Upscale & Save variant overrides the disabled-detection hook to always report "side branch active" - unlike the FaceProcess boundary, it never claims to be globally disabled, because there's no global switch to be off.

Two properties you should hold onto. This is a session cache: a ComfyUI restart clears the image boundary caches; only the video segment path has a deliberate cross-session continuation contract. And a cache is not a project format - the README says it plainly. Don't treat temp/cmk/ as your archive.

Inputs and outputs

Every input is optional, which is what lets the node decide whether to bother evaluating them:

  • MODEL (opt) (CMK_MODEL_PIPE) - passed through; read-only, never serialised into the cache.
  • IMAGE - the payload being cached.
  • LOG (CMK_LOG_PIPE) - documentary, cached alongside the image so the log you read matches the image you got.
  • diagnostic (CMK_DIAGNOSTIC) - cached with the rest.

Outputs are the same four types back out: MODEL, IMAGE, LOG, diagnostic. It's a straight passthrough when everything is present, and a from-disk replay when it isn't.

Install

This is a CMK/Developer/Boundary & Cache node - internal infrastructure that ships with the pack rather than something you add deliberately. Installing means installing the pack:

Manager → search CMK Flow → install → restart. Manual:

cd ComfyUI/custom_nodes
git clone https://github.com/CMKFlow/cmk_nodes
python3 custom_nodes/cmk_nodes/scripts/install_cmk_requirements.py

For upscaling specifically, you also want your upscale models where ComfyUI can see them (models/upscale_models), since the Smart Upscaler this boundary usually fronts picks RealESRGAN-class 2x/4x models from there. The resource checker knows the filenames the shipped workflows expect:

python3 custom_nodes/cmk_nodes/scripts/check_cmk_resources.py --models-root "/path/to/shared/models"

Common issues

  • "HIT" but the image is stale. The key is the node's own identity plus its module parameters, so editing something inside the cached branch without changing the boundary's inputs can leave you looking at yesterday's pixels. If in doubt, change a parameter on the boundary's own module or restart ComfyUI.
  • STORE_FAILED in the console. The disk write under ComfyUI/temp/cmk/ didn't complete - usually permissions or a full volume.
  • Cache never hits, ever. Unchanged parallel branches are supposed to resolve to HIT within one session. If yours never does, something upstream is returning a new object every run - a random seed, a float("NaN") always-rerun node, or a node whose output identity isn't stable. That's the classic ComfyUI always-dirty trap and it nullifies caching for everything behind it.
  • The node "runs" for a beat even when disabled. Expected. A visible node appears briefly in graph evaluation; the ms-level execution time is the contract, not zero.
CategoryCMK/Internal/Boundary & Cache

Inputs (4)

NameTypeDefaultDescription
MODEL (opt)optCMK_MODEL_PIPE—
IMAGEoptIMAGE—
LOGoptCMK_LOG_PIPE—
diagnosticoptCMK_DIAGNOSTIC—

Outputs (4)

NameTypeDescription
MODELCMK_MODEL_PIPE—
IMAGEIMAGE—
LOGCMK_LOG_PIPE—
diagnosticCMK_DIAGNOSTIC—