for loop over ralphy template use by hand; you use ralphy batch. The verb exists for three reasons that don’t exist when you generate one video at a time — cost deduplication (the master shots get generated once, not N times), parallel render with bounded concurrency, and a structured cost rollup at the end so you know what 10 variants actually cost.
What a batch is
A batch is a set of projects spawned from a single template plus a list of per-variant tweaks. Each project is a real project — own ID, own folder underworkspace/projects/, own logs, own manifest, own final render. The batch is the wrapper that creates them, runs them, and reports on them.
The workspace/batches/<batch-id>/state.json file tracks the in-flight state across the projects in the batch. The batch ID format is the standard {context}-{NNN}, same as project IDs.
The two entry points
Interactive, from a template
The simplest path. Pick a template, ask for N variants, let Ralphy spawn the projects:variations.json is a JSON array, one object per variant. The object’s keys are the slots or template parameters you want to vary:
--ref on every project’s scene gens — the cost deduplication that makes batch worth using.
Vary axis, from a base project
When you already have a successful single video and want to ship variants on a specific axis (the hook, the music, the persona, the aspect ratio):--axis is one of the named axes the template supports (hook, body, cta, music, etc.) per the typed Scene[] schema from the scenarist playbook. The --variants-file carries N objects with the swap values. --dry-run previews what would be created without writing.
Concurrency and parallel render
--concurrency controls how many projects run in parallel. The default is 3; bump it if you have headroom and a stable network. Per-model concurrency caps still apply — openai/gpt-5.4-image-2 is capped at 1 concurrent call per OpenRouter key, so batch fan-out for that model serializes regardless of your --concurrency setting. google/gemini-3-pro-image-preview tolerates 4+ in parallel.
The batch state machine tracks which projects are pending, in-flight, complete, or failed:
The cost rollup
When the batch finishes, the rollup lands as part of the status output and as a markdown file atworkspace/batches/<batch-id>/COST_ROLLUP.md. It breaks down by project and by modality (image, video, voiceover, music, render) so you can see where the spend went:
ralphy batch show <id> --json | jq.
The post-batch postmortem
When a batch completes, the producer playbook auto-generates aPOSTMORTEM.md at workspace/batches/<batch-id>/POSTMORTEM.md (or invokes the /postmortem skill on a long batch). The postmortem captures lessons learned, model picks that worked or didn’t, the cost rollup, and any CLI gaps the agent had to work around. The next batch starts at a higher skill level — that’s the design.
You can trigger a postmortem manually any time after a batch with /postmortem in chat. The skill writes six structured files under workspace/batches/<batch-id>/postmortem/ covering chronological history, lessons, bugs, cost rollup, and workflow fixes. Detail in the /postmortem skill.
Perf target
The producer playbook’s batch target is ≤ 25 minutes wall-clock for 10 videos (docs/perf-targets.md). If your batch is on track to exceed 50% over that (38+ minutes for 10), the producer playbook says report before continuing — usually the cause is a stuck job, a saturated model concurrency, or a missing asset that’s blocking the pipeline.
Calculate ETA before kickoff with --dry-run:
Sharing a batch
A batch’s projects are normal projects — they can be exported viaralphy profile export, shared via PR to the ralphy-assets companion repo as a worked example, or extracted into a new template via ralphy template create --from-project <id> after picking the winning variant.
If you want a teammate to see exactly what the batch produced (without sharing 50MB of renders), ralphy profile export <nick> defaults to skipping renders to keep PRs small. Pass --include-renders if you want to share the mp4s too.
Why the verb exists
You could, in principle, write a shellfor loop that calls ralphy template use and ralphy render N times. You shouldn’t, and the producer playbook is explicit about it. The reasons:
- Cost dedup. The persona master shot gets generated once, not N times. Same for the location plate. That’s 30%+ savings on most multi-scene batches.
- Bounded concurrency. The batch runner respects per-model concurrency caps; a hand-rolled loop hammers OpenRouter and gets rate-limited.
- Structured output. The cost rollup, the postmortem, the per-modality breakdown — all generated for free by the batch wrapper. A shell loop gives you N detached projects with no aggregated view.
- Failure recovery. A failed project in the middle of a batch doesn’t kill the whole run; the runner marks it failed, moves on, and the rollup shows it. A shell loop just exits.
ralphy batch. The four reasons above are why.
Related
- Profiles — sharing a batch’s output via PR
- Reviewing and iterating — iterating on a single project before extracting to a batch
producer.md— the playbook this page paraphrasesdocs/perf-targets.md— the perf budget