Nodes/CMK Flow/CMK Boundary Cache
ComfyUI Node

CMK Boundary Cache

The boundary that stops your detailer running twice

By CMKFlow·Created 3 months ago·Updated 2 days ago· 6
CMK Boundary Cache
  • MODEL
  • IMAGE
  • LOG
  • MODEL
  • IMAGE
  • LOG

Upscaling and re-sampling a face crop is the expensive part of any detailing workflow, and CMK Flow lets you run several detailer branches side by side - one for eyes, one for skin, a separate one for hands. Without something in the middle, every one of those branches re-runs the whole chain whenever anything upstream twitches. CMK Boundary Cache is that something, and it's the most quietly clever node in the pack.

What it is

It's a three-in, three-out node: MODEL (CMK_MODEL_PIPE), IMAGE and LOG in; the same three out. That's all it looks like it does, and if you only read the graph you'd assume it's a reroute. It isn't. It's a lazy evaluation boundary with a fingerprint-keyed cache behind it.

Category is CMK/Developer/Boundary & Cache and the class is flagged DEV_ONLY, so it lives inside CMK's shipped detailer workflows rather than on a tutorial canvas. Three instances of it exist with the same display name - the detailer one, a face-process one and a FaceRebuild one - and they're separate nodes with separate caches.

How it works

The trick is that all three inputs are declared lazy. Before ComfyUI evaluates anything upstream, it asks this node's check_lazy_status, and that method answers with an empty list when it can already produce the answer. An empty list means "request nothing" - the upstream detailer branch is skipped entirely, not evaluated and discarded. That's what makes the cache save actual GPU time rather than just memory.

Whether it can answer depends on two things it computes from the prompt graph:

  1. A node fingerprint - the boundary's own identity plus a schema version (cmk_detailer_boundary_v3 for this one). Change the node, and the key changes.
  2. An upstream dependency manifest - the revision markers of the detailer branches feeding it. The merged cache only accepts a hit if that manifest matches the branch revisions currently materialised. So editing one branch's settings updates the merge and the boundary while untouched sibling branches still come from their own cache.

There's also a static short-circuit: if the whole detailer module is disabled - the prepare node's global enable boolean is off - the boundary declares itself DISABLED_PASSTHROUGH_READY and just hands the three inputs through. No cache lookup, no upfront work.

Where the cache lives: ComfyUI/temp/cmk/detailer_boundary, with a last_status.json writing out MISS, STORED, HIT_READY and friends as it goes. Handy when you're trying to work out whether your "instant" second run was a cache hit or just a small image.

Why you'd care

Because it changes the economics of modular detailing. The whole reason to split a detailer into separate branches is to tune them independently - the trade has always been that each tweak re-runs everything. Here you get the first run paying full price (MISS → STORED, expected after a restart, a code change or a cache clean) and subsequent runs resolving as HIT for the branches you didn't touch. The manual describes exactly that as the intended behaviour, and calls caching a temporary accelerator, not a project format. That last part matters: this is not a "save my work" feature.

Install

It arrives with the pack. Manager: search CMK Flow → install the CMKFlow entry → restart. Manually, from the folder holding main.py:

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

You want CMK dependency check: OK. The detailer itself is CMK's own implementation - its own SEGS handling, its own detector wrapper, its own SAM loader - so it does not require the Impact Pack, which is a pleasant surprise in a category where everything else assumes it. The detector models still have to exist: YOLO checkpoints under models/ultralytics/bbox or segm, SAM checkpoints under models/sams. The resource check can audit and fetch those:

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

Issues worth knowing

A restart empties the cache - it lives in temp. Only the pack's video path has a cross-session continuation contract. So if run one is slow and run two is fast, that's working as designed; if both are slow after a restart, that's also working as designed.

The usual reason a cache "doesn't hit" is that the dependency manifest moved: a branch revision changed, or a schema version bumped in a pack update, which invalidates everything once. If you're debugging it, read ComfyUI/temp/cmk/detailer_boundary/last_status.json rather than guessing from timings.

And don't use the boundary as a place to stash outputs you care about. It's temp, it's not portable, and the pack says so out loud.

CategoryCMK/Internal/Boundary & Cache

Inputs (3)

NameTypeDefaultDescription
MODELCMK_MODEL_PIPE—
IMAGEIMAGE—
LOGCMK_LOG_PIPE—

Outputs (3)

NameTypeDescription
MODELCMK_MODEL_PIPE—
IMAGEIMAGE—
LOGCMK_LOG_PIPE—