Image Ledger · Tracked Image Loader
The queue with all the knobs showing
- image
- mask
- job_ticket
- source_path
- remaining_pending
- completed
- status
If you're rendering an image library into clips, the moment that hurts is the one where you can't remember which sources you already did. Image Ledger · Tracked Image Loader is the full-fat loader from that pack: it picks an unprocessed source out of ComfyUI/input, reserves it, and marks it complete only when a real video lands. The Visual Queue node is the same engine with five widgets; this one shows you ten, which is the trade you make for control over queue order, reservation timing, and continuous runs.
What it's for
Its node description is the summary: selects an unprocessed source image from ComfyUI/input; the image is marked complete only after the final video is saved successfully. That last clause is the reason to use a ledger at all instead of a shell loop - "loaded" and "done" are different states, and only the second one should remove an image from your backlog.
Take the explicit-node route when you don't want the global panel writing into a LoadImage of its choosing. You wire the source yourself, so there's no guessing which loader in a big graph is the first-frame one.
How it works
Four moving parts, in order.
Indexing. The node walks the source folder, finds files matching your extension list, and computes a SHA-256 for each, caching results so later sessions don't re-hash the world. That hash - not the filename - is a source's identity, which is why a renamed copy still counts as the same image.
Reserving. reserve_next picks a pending item and marks it running under a token with a lease. Concurrent jobs can't take the same image, and a preview you already looked at gets reused rather than re-drawn.
Loading. It re-checks the file's size and mtime against what it registered; if the file changed underneath it, it releases the reservation and errors instead of rendering something the ledger can't account for. Then it loads through ComfyUI's own LoadImage via an input-relative path, so junctions and symlinked libraries under input/ work.
Handing off. It emits a job_ticket JSON blob - token, ledger name, continuous-queue flag - which is what the commit node closes the loop with. sync_legacy_history additionally imports metadata from pre-existing videos in output/video once per session, and stops selection if anything there is unresolved rather than risk a repeat.
Inputs and outputs
The ones a beginner actually sets:
- source_subfolder - e.g.
AIforComfyUI/input/AI; empty scans the input root. The tooltip on recursive is worth heeding: "Disable this when scanning the input root to avoid temporary folders." It defaults off here for that reason, while the simpler node defaults it on. - selection_mode -
random_no_repeat(the default, a stable shuffle without replacement), orname_asc,name_desc,oldest,newest. Pick a deterministic one when you want a run you can resume predictably by hand. - auto_queue_next - off by default, and the tooltip is a precondition rather than a description: "Enable only after confirming that the workflow commits its final video." Turn this on before your commit node is proven and you'll queue your way through a library without anything ever being marked done.
Then the knobs most people never open: shuffle_seed (default 1337 - change it to re-roll the order without disturbing completion history, since the ranking is derived from ledger name + seed + content hash), lease_minutes (10 to 10080, default 1440) for how long an uncommitted task stays reserved, plus extensions, sync_legacy_history, and legacy_video_glob. campaign is the ledger name - the loaders ship it hidden, and loaders sharing a name share completion history.
Outputs: image and mask into your sampler chain, job_ticket into the commit node, source_path as a string for filenames, remaining_pending and completed as ints, and status as the familiar Pending 42 | Running 1 | Done 310 | Unique 352 | Duplicates 7.
Install
Manager → Custom Nodes Manager → search Image Ledger, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Rona1do/ComfyUI-Image-Ledger.git
Restart ComfyUI. The pack's requirements.txt adds nothing - Pillow, SQLite and aiohttp come from ComfyUI - but the commit half of the loop needs VideoHelperSuite for its VHS_FILENAMES type. Source libraries have to live under ComfyUI/input; a directory link/junction there can point at another drive.
Common issues
"No pending images remain in this ledger." Everything's done, or your folder/extension filters match nothing. The message includes the counts, which usually says which.
"The source image changed after indexing. Run again to refresh its hash." Something rewrote the file - a sync client, an upscaler writing in place. The node released the reservation instead of rendering an unaccounted image; just run again.
Selection stops with a legacy-import error. sync_legacy_history is on and some old video's metadata couldn't be resolved. Run the Import Video History node with dry_run off to reconcile it, or turn the toggle off.
It never finishes anything. No commit node, or one missing its job_ticket wire, or a VideoCombine configured to save into temp. Reservations will pile up at Running until their lease expires; the Recovery node clears them.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| campaign | STRING | image-ledger-default | Loaders with the same name share completion history. |
| source_subfolder | STRING | For example, AI means ComfyUI/input/AI. Leave empty for the input root. | |
| recursive | BOOLEAN | false | Disable this when scanning the input root to avoid temporary folders. |
| selection_mode | COMBO | random_no_repeat | random_no_repeat is a stable shuffle without replacement. |
| shuffle_seed | INT | 13370–2147483647 | — |
| lease_minutes | INT | 144010–10080 | How long an uncommitted task stays reserved. |
| auto_queue_next | BOOLEAN | false | Enable only after confirming that the workflow commits its final video. |
| extensions | STRING | .png,.jpg,.jpeg,.webp,.bmp,.tif,.tiff,.avif | — |
| sync_legacy_history | BOOLEAN | true | Incrementally imports metadata from existing videos once per session. |
| legacy_video_glob | STRING | *.mp4 | — |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| job_ticket | STRING | — |
| source_path | STRING | — |
| remaining_pending | INT | — |
| completed | INT | — |
| status | STRING | — |