Parallel Execution

SkillDev tools

Parallel execution patterns for montaj, load when workflow has multiple clips or foreach steps

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Parallel Execution skill

What this skill tells your AI

The instructions your AI receives, as published by thesampadilla/montaj in skills/parallel/SKILL.md and read by ahel’s review.

Important: Claude Code's Bash tool executes sequentially — multiple Bash calls in the same turn queue one after another. They do NOT run in parallel. Use the patterns below for true parallelism.

Step-level — same step, multiple clips

For foreach steps on independent clips, use a single Bash call with background jobs:

out0=$(curl -s -X POST http://localhost:3000/api/steps/transcribe \
  -H "Content-Type: application/json" \
  -d '{"input": "/path/clip0.MOV", "model": "base.en"}') &
out1=$(curl -s -X POST http://localhost:3000/api/steps/transcribe \
  -H "Content-Type: application/json" \
  -d '{"input": "/path/clip1.MOV", "model": "base.en"}') &
# ... repeat for each clip
wait
echo "$out0"; echo "$out1"  # parse results after all complete

Use for any independent foreach step: waveform_trim, transcribe, rm_fillers, probe, snapshot.

Do NOT use background jobs for encoding steps. See Encoding steps below.

Encoding steps — materialize_cut, remove_bg

Encoding steps are memory-intensive per instance (full libx264 encode + frame buffers). Fanning them out unbounded across N clips will exhaust memory on 4K footage. Use batch mode with the built-in concurrency cap instead of background jobs:

# materialize_cut — batch mode, 2 concurrent encodes (default)
montaj materialize-cut --inputs clip0_spec.json clip1_spec.json clip2_spec.json
# → JSON array of output paths

# raise to 3 only on machines with 32GB+ RAM and 1080p or smaller footage
montaj materialize-cut --inputs clip0.MOV clip1.MOV --workers 3

# remove_bg — always use --inputs; GPU processes sequentially, CPU parallelises with workers
montaj remove-bg --inputs clip0_cut.mp4 clip1_cut.mp4 clip2_cut.mp4
# → JSON array of {nobg_src, nobg_preview_src} objects

remove_bg is long-running (minutes per clip on MPS/GPU). Always run it in the background when using the Agent tool or HTTP API so the agent remains responsive.

waveform_trim native batch

Preferred over background jobs — pass all clips in a single call:

# HTTP
curl -s -X POST http://localhost:3000/api/steps/waveform_trim \
  -H "Content-Type: application/json" \
  -d '{"inputs": ["/path/clip0.mp4", "/path/clip1.mp4", "/path/clip2.mp4"]}'
# → returns JSON array of trim specs: [{"input": "...", "keeps": [...]}, ...]

# CLI
montaj waveform-trim clip0.mp4 clip1.mp4 clip2.mp4
# → JSON array of trim specs printed to stdout

Clip-level — multiple steps per clip (swarm)

When each clip needs 3+ sequential per-clip steps, background jobs get unwieldy. Use one subagent per clip:

  1. Identify the fan-out point: every step declared foreach: clips
  2. Identify the fan-in point: the first step with no foreach that actually consumes every clip's output — an agent-authored task in the clip-based workflows (select-takes, overlay). Not every non-foreach step is a fan-in: broll's whole vo_* chain is non-foreach because it runs on the voiceover alone, in parallel with the footage pass
  3. Spawn one subagent per clip — each receives: clip path, steps to run, project id, editing prompt
  4. Cap at 4 concurrent clip agents to avoid resource contention
  5. Wait for all subagents to complete, collect output paths
  6. Fan in: hand the collected paths to the non-foreach step and continue

There is no join step. Nothing concatenates the per-clip outputs into one file: the surviving keeps become tracks[0] items with their own inPoint/outPoint, and the render engine assembles them in a single pass at the end.

Use when a clip needs 3+ sequential steps — subagent coordination overhead is worth it beyond that threshold.

Dependency waves

Workflow steps declare needs: [step_ids]. Identify waves of ready steps (all needs met) and execute each wave with the appropriate parallel pattern before moving to the next.

Example — default workflow:

WaveStepsPattern
1probe, snapshot, waveform_trim (per clip)Bash & or waveform_trim batch
2rm_nonspeech (per clip)Bash &
3transcribe (per clip)Bash &
4select-takesSequential — the fan-in; needs every clip's transcript
5rm_fillers (per clip)Bash &
6transcribe_final (per clip)Bash &
7overlaySequential

Assembly is not a wave. The render engine reads the finished tracks and encodes once, at render time.

Signals

GitHub stars
25
Forks
11
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
parallel
Source
github.com/thesampadilla/montaj