TS Batch Source
Turn one graph into a hundred independent runs
- item
- index
- total
- seed
If you've ever wanted to caption a folder of images, generate a hundred distinct prompts, or re-render the same workflow against fifty inputs, this is the node you reach for. TS Batch Source turns a folder, a text file, or a plain count into a job list - and because of how ComfyUI's own batch engine works, everything wired below it runs once per item, independently. A hundred captions become a hundred separate model calls, not one conversation that keeps growing until the model forgets the first picture.
How it works
When a node's output is a list, ComfyUI executes the downstream branch once per element. That's the engine behavior this node leans on: item comes out as a list, so the whole branch below iterates, and each iteration is its own run. It's also fingerprint-aware - it hashes the folder's contents (name, modification time, size), so dropping new images in makes it re-run rather than quietly processing yesterday's set from cache.
The modes that matter
- Images in folder - one job per image, in natural order, so
img2comes beforeimg10and you don't get a surprise reorder at the ten-image mark. - Lines in text file - one job per non-empty line. This is the mode that closes the loop with TS Batch Write (see below).
- Count only - N numbered iterations, for when you just want to loop a workflow N times.
Set the mode, give it a path (folder or text file), and you're mostly done. The two fields worth knowing beyond that: start_at skips this many items so a run that stopped halfway resumes without redoing the finished part (and keeps the original numbering), and limit caps the run. 0 on limit means no limit.
The outputs
item- one path, line, or number per job. Wire this downstream.index- position in the job list, starting at 0.total- how many items the job has; the same value for every item.seed- a distinct seed per item, derived from theseedwidget.
That seed output is the quiet hero. A seed widget on a model node holds one number for all hundred calls, so a hundred iterations of the same task come back identical. This output hands every item its own derived seed - reproducible from the base value, different from its neighbours. Note it's not just base + i: neighbouring seeds are a poor source of variety, so it hashes the pair instead.
⚠️ Read one_per_run before a long batch
With the default (list) mode, ComfyUI finishes every copy of one node before it starts the next. Two consequences: results reach disk only after the model has done every item, and a node that stamps per-item metadata - like TS Image Prompt Injector - gets overwritten by the last item before the save nodes run, so every picture ends up with the same prompt.
Flip one_per_run on and set ComfyUI's Batch count to the number of jobs. Each queued run is then a full pass through the graph: the picture is generated, stamped, and saved before the next job starts. Slightly slower, and the only correct choice when you want to watch results arrive or need honest per-image metadata.
It emits paths, not pictures - deliberately
A hundred 4K frames passed along as images would sit in the output cache (roughly 10 GB) before the first caption is written. TS Batch Load Image reads them one at a time instead, so peak memory stays at a single frame. Pair the two and you can caption a folder that would otherwise OOM your box.
The loop worth knowing: TS Batch Write in "one line per item" mode writes a text file that this node reads back in "Lines in text file" mode - captions become generation jobs with no conversion in between.
Install & troubleshooting
Ships in comfyui-timesaver (AlexYez). ComfyUI Manager → search Timesaver → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/AlexYez/comfyui-timesaver
cd comfyui-timesaver
python -m pip install -r requirements.txt
Restart ComfyUI fully. No models, no heavy deps for this node. Two failure messages you might actually see: "Mode 'X' needs a path" when the mode needs a folder/file and you left it empty, and "Nothing to do: the job list is empty after start_at=… and limit=…" - usually a start_at that skips past everything. The typical chain is TS Batch Source → TS Batch Load Image → TS Qwen 3 VL → TS Batch Write.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| mode | COMBO | Images in folder | Where the jobs come from: image files in a folder, non-empty lines of a text file, or simply N numbered iterations. |
| path | STRING | Folder or text file. Ignored in 'Count only' mode. | |
| count | INT | 101–10000 | How many iterations to emit in 'Count only' mode. |
| start_at | INT | 00–1000000 | Skip this many items from the front. Use it to resume a run that stopped halfway instead of redoing the finished part. |
| limit | INT | 00–1000000 | Stop after this many items. 0 means no limit. |
| seed | INT | 00–4294967295 | Base for the per-item seed output. Every item gets its own derived seed, so repeated iterations of the SAME prompt come back different instead of identical. |
| one_per_runopt | BOOLEAN | false | Hand out ONE job per queued run instead of the whole list. Set the Batch count in ComfyUI's queue to the number of jobs and each run becomes a full pass through the graph — the picture is saved and its metadata stamped before the next job starts. Needed whenever results must appear as they are made, or when a node writes per-item metadata (TS Image Prompt Injector). With the list instead, ComfyUI finishes every copy of one node before moving to the next, so results land only at the very end. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| item | STRING | One job per element: an image path, a text line, or a number. |
| index | INT | Position of the item in the job list, starting at 0. |
| total | INT | How many items the job has. The same value for every item. |
| seed | INT | A distinct seed per item, derived from the seed widget. Wire it into the sampler or LLM seed — a widget alone would hand every iteration the same number. |