2026-08-28 · Updated 2026-08-28 · 11 min read
Parallel vs sequential Ralph loops
A topology decision for Ralph-shaped work, answered with four explicit safety criteria instead of throughput arithmetic: isolation, quota, evidence, and recovery each compared across one board-driven sequential loop and a capped pool of bounded parallel lanes, ending in a four-question pass that serializes any work a criterion cannot vouch for.
By Juno AI INC · ralph-loop · parallel-agents · yylo
The question usually arrives as arithmetic. You have a board of Ralph-shaped work — small units, one bounded pass each — and a hunch that two loops finish twice as much by morning. The hunch is the folklore this page replaces, because a second loop does not just add a second worker; it changes who may write where, how much can be spent at once, what evidence multiplies, and what a failure strands. Those four effects are the actual decision, and each one has a criterion you can check before anything launches.
Scope first, so the neighbors stay whole. The technique's origin, vocabulary, and per-pass mechanics belong to the Ralph loop reference; whether a bounded workflow or a raw loop suits the work better at all is a different trade, owned by the run-anatomy comparison. This page assumes the work is already bounded units on one board and owns exactly one question: run the board through one sequential loop, or through several concurrent lanes. Every claim below about YYLO's runners was verified against the committed script templates and CLI source on 2026-08-28; the four criteria and the verdict logic are this site's original framework. Two siblings hold the depth on either side and are linked rather than repeated: the whole parallel cycle, stage by stage, is the complete parallel workflow, and the admission, cap, and lane-safety mechanics are safe parallel execution. This page contributes only the comparison: which topology the work has earned, and why.
Name the shapes before comparing them
Folklore parallelism is N terminals with the same while-loop pasted into each. Each copy restarts the worker from scratch no matter what the last pass achieved, every copy edits the same tree unless you deliberately gave it its own, and nothing anywhere counts passes or watches for stalls. That form fails all four criteria before launch, and diagnosing it after the fact is another page's job. The honest comparison is between the two bounded shapes YYLO ships, and they are less symmetrical than the folklore assumes.
The sequential shape is run_until_completion.sh: one driver that checks the board for open work ahead of the first pass and rechecks it after each one, skips the agent entirely when nothing is open, dispatches a single bounded pass when work remains, and snapshots board state between passes so a run making no progress can be stopped by machinery instead of by your interrupt reflex. The parallel shape is parallel_runner.sh: you hand it an admitted list of task IDs, and it runs lanes concurrently under a cap you set. Here is the detail that surprises everyone who arrives from the folklore: the committed runner pins every task lane to a single iteration and launches it with hooks off. A task lane is one invocation that never re-checks the board, so no amount of launching turns the task pool into N loops.
So the real comparison is one board-driven loop against one capped pool of single passes — both reading the same ledger, both recording evidence, both stoppable. Which worker occupies a lane is a separate question entirely; mixing Claude, Codex, and Pi passes under either shape is the multi-harness loop guide's job. What the four criteria decide is only the topology.
Isolation: one writer, or several named surfaces
The sequential loop has a property no pool can imitate: the working tree has exactly one writer at any moment. Passes never overlap, so when the tree is broken in the morning, the breakage belongs to exactly one pass, findable from one thread of evidence. Shared state still exists — the board — but the board is a record with an owner and transitions, not a file two processes edit at once.
A parallel lane looks isolated and is only half isolated. Each lane runs as a separate process and gets a prompt file of its own, a task log of its own, and its own result record; none of that touches a sibling. But every lane starts in the same checkout, so the process wall separates records, not files. Two lanes that edit one file, or regenerate one generated artifact, are coupled in fact regardless of what the board declares — in one checkout the collision is immediate, both lanes writing the same bytes, and moving each lane to a worktree of its own only defers it to merge time.
The criterion, then, is nameable surfaces, and it is a planning-time test: write down the path set each unit may touch, and read the lists aloud. If any path appears on two lists, those two units are not parallel work — declare the ordering and serialize them, or give each lane a place of its own with the worktree-per-agent topology the Git worktrees guide owns. An unnamed path set is not a neutral fact; it is a decision to discover the coupling in production. Sequential wins this criterion by default, and parallel earns it only when every list is written and disjoint.
Quota: name the smallest real limit
Sequential spend is serial. The worst honest night costs passes times cost-per-pass, and two machinery bounds apply before your patience does: an outer pass count you can pin when the run deserves one, and the staleness stop that ends a run whose board snapshot stops changing — so a stuck board cannot turn budget into the look of work. Raising sequential throughput means raising a number you chose, in daylight, with those stops still armed. The design logic behind pairing numeric and semantic bounds is bounded failure design's to teach; this page only counts what it costs.
Parallel spend is the same total at a different shape. The --parallel cap — 3 unless you say otherwise — bounds how many lanes run at once, and since each lane is one provider session, the cap is also your concurrent session count. N lanes buy wall-clock, not discount: the pool finishes the list sooner while spending what the same passes would spend serially, and the worst concurrent exposure is cap times cost-per-pass. The cap throttles concurrency; it confers no correctness — that was settled by admission and isolation above, or never at all. Provider quota flags ride the whole pool through --subagent-args, so a lane that meets an hourly limit can park and wait rather than fail mid-batch:
The criterion test: name the smallest real limit among provider concurrency, machine headroom, shared external quotas, and review capacity — then set the cap under it. Parallel earns this criterion only when the bottleneck is genuinely wall-clock and every named limit has headroom. A team that cannot name its limits has not chosen a topology; it has chosen to find them empirically, concurrently, at night.
Evidence: richer records, weaker gates
What a run leaves behind is where the two shapes trade rather than rank. The sequential side runs with the project's lifecycle hooks live: every pass executes under the configured hook points, per-pass records accumulate on their own, and the between-pass board snapshot makes absence of progress itself an observable event — the run that stalls ends with its own exit status, distinguishable from a finished one without reading any prose.
The parallel side answers with structure. Each lane writes a JSON record of its own — exit code, session id, cost, wall time, the worker that ran it, the extracted response — and one aggregation sits above the lanes recording totals, the failed IDs with their sessions, and summed cost, while a status file lets a wait helper turn a background pool into a deterministic step. Fanned out honestly, the pool's evidence is more uniform than N hand-watched terminals could ever be.
But the template encodes an asymmetry that decides real deployments: lanes launch with hooks disabled. The in-pass gates that fire on every sequential pass — the checks, tripwires, and per-pass hooks a hardened loop leans on — do not fire inside a lane. The gate does not disappear; it moves into the task body, whose finish line has to carry its own acceptance commands, because no hook will supply them mid-lane. Designing that gate is the loop-hardening guide's job; the topology lesson is that parallel evidence is structurally richer and behaviorally thinner per pass.
The criterion test is reading speed. N lanes produce N records in the wall time one loop produces one, and closing tasks means actually reading responses, diffs, and commits — the aggregation points you to that reading; it never replaces it. Review capacity was a quota a moment ago; here it is the reason. A pool whose residue nobody has time to read has not produced evidence — it has produced backlog with better formatting.
Recovery: what a failure strands
Sequential failures arrive one at a time, which is half of their mercy. A pass that exits nonzero is logged and the loop continues — partial completion is expected loop behavior, and the task the pass failed to close is still on the board for the next pass to retake. A board that stops moving trips the stale hook and ends the run with the distinct exit status, leaving a diagnosis rather than a mystery. Whatever the morning holds, it holds one thread: one run log, one board state, one place the night went wrong first.
Parallel failures strand a lane, and the strand is the unit of repair. The failed lane's record names its exit code and the session to reopen, which splits recovery into two honest moves: a conversational failure — the worker lost its place, met a limit, or quit early — continues from that session, while a task that was wrong gets its body fixed and its ID rerun alone. The lanes that succeeded keep their evidence and their commits untouched; re-running them pays for the work twice and piles fresh runs on top of records that were already fine. Sessions end as deliberately as they start — one named session with --stop, everything only with --stop-all:
The criterion test: for each failure class you expect — conversational, wrong task, broken tree, exhausted quota — name the retry you would perform, out loud, before launch. Sequential recovery is forgiving because it is slow and singular; parallel recovery is cheap exactly when the lane records exist and the retry is named. A failure class with no named retry is a criterion failure, whatever the throughput arithmetic promised.
The decision in one pass
The four criteria collapse into four questions, asked in order, each answered with a sentence you would defend in review. Any question you cannot answer serializes the work — not as a punishment, but because the unanswered question is where the night will go wrong.
- Isolation. Can you list every unit's path set, with no path on two lists?
- Quota. Can you name the smallest real limit, and is your cap set below it?
- Evidence. Who reads N records in the morning, and does every task body carry its own finish line?
- Recovery. Can you name the retry for each failure class you expect?
Four yes answers earn the pool, and the cap becomes the smallest named limit rather than the task count. Anything less runs sequentially — which is not a consolation prize, because the sequential loop with its stops armed is the shape that teaches your board everything the pool will later assume: units with verifiable outcomes, admission through readiness, per-pass evidence. One boundary closes the decision: if the units need each other's responses rather than just each other's completion, neither topology is right — that work is a chain, and the ordered alternative is the runner-choice guide's question, not this one's.
Start sequential, earn the width
The pool is not a different discipline from the loop; it is the same discipline with the cap raised. So earn it in that order. Run the board sequentially first and watch what one bounded pass does to one unit — the first evening of that practice is the starter walkthrough, step by step. When the four questions all have answers, raise the width on the same board, with the same gates living in the same task bodies, and read the aggregation in the morning instead of N terminals. If the night has already gone wrong somewhere else, name the mode first: the diagnostic catalog turns the evidence you have into the failure you had. Operational reference for every flag on this page lives with the runners themselves — Run Until Completion and Parallel Runner.
The arithmetic that opened this page was never wrong about speed; it was wrong about what speed costs to keep safe. Install YYLO with npm, hand the board one bounded, evidence-producing task at width one, and let four defensible sentences — not a hunch — be the thing that adds the second lane.