Back to articles

Running parallel agent attempts from one starting state with copy-on-write branches

Prepare an agent environment once, fork it per attempt with copy-on-write disk branches or sandbox forks, score the results and keep the winner. What it costs and where it stops working.

9 min read

Running parallel agent attempts from the same starting state works best when setup is done once and each attempt gets its own copy-on-write fork. Each agent can try things without getting in the others’ way, and the winning state can be kept without undoing the losing edits. Archil makes this pattern concrete through disk branches and sandbox forks, though cheap branching does not mean free compute or isolation from every outside system.

Why parallel agent attempts fail without isolated environments

Two agents editing the same file can see each other’s unfinished state, overwrite each other’s changes, and leave the file in a state neither meant it to be in. The last write wins through a scheduling accident. A better prompt cannot fix this because the failure is a filesystem concurrency problem.

Giving each attempt a workspace through git stashing, temporary directories, or container clones adds state-management work, and these workarounds cannot capture all filesystem modifications. Fork, Explore, Commit explains why composing existing OS mechanisms in userspace is fragile. The pieces introduce race windows, error-prone cleanup after partial failures, and ordering dependencies that break correctness. When bookkeeping eats that much of the run, the agents are not the only things that need a better working environment.

The prepare-once, fork-per-attempt pattern and why it solves the problem

Preparation is separated from exploration. Setup produces a known-good base with packages installed, the repo checked out, and dependencies resolved. Each attempt then receives an isolated copy-on-write fork of that base. All attempts begin with the same state, rather than with whatever happened to survive the previous attempt. There is no per-attempt setup and no divergence before the agent starts work.

Copy-on-write makes that separation affordable because a fork stores only its own changes. Attempts can run in parallel, take different approaches, and fail without changing their siblings’ state. Once the results are scored, the winner is committed and the rest are discarded. Losing edits never need to be reversed in a shared working tree because they never reached it. Cleanup is no longer needed for correctness, though how branch resources are freed still depends on how the system is built.

Fork, Explore, Commit gives this lifecycle an explicit name, namely fork, explore, and commit/abort. Its first-commit-wins resolution automatically invalidates sibling branches once one branch commits. That is a research design for making the whole lifecycle a systems primitive, rather than a collection of cleanup scripts with a positive attitude. The general pattern depends on keeping a common base, letting each attempt explore on its own, and choosing which result to keep.

Copy-on-write branching at the disk level

Archil handles the storage part through disk checkpoint-and-branch, which takes approximately 90 ms no matter how big the disk is. Branching doesn’t copy the data on the disk. As a result, creating an attempt has the same branching cost whether the base holds 1 MB or 100 GB. That size independence is the important distinction from physical cloning or git-based workspace management.

The workflow starts with a checkpoint of the prepared disk and creates one branch per attempt. Each branch is an independent writable fork that can be mounted with archil mount --branch on any machine and used like a normal POSIX filesystem. Agents call open(), write(), and fsync() without needing to know that their filesystem is a branch. Once the attempts finish, the workflow scores their results and keeps the winning branch. With the CLI, the setup looks like this:

# Checkpoint the prepared disk from a client that has it mounted
archil checkpoints create /mnt/archil base
 
# One writable branch per attempt
archil branches --region aws-us-east-1 create dsk-0123456789abcdef attempt-1 --from-checkpoint base
archil branches --region aws-us-east-1 create dsk-0123456789abcdef attempt-2 --from-checkpoint base
 
# Mount a branch wherever the attempt runs
sudo archil mount myorg/mydisk /mnt/attempt-1 --region aws-us-east-1 --branch attempt-1

Writes are durable once fsync returns, and they are copied to the backing store in the background. Branch state therefore survives a restart. Durability keeps an attempt’s work safe, while isolation keeps that work from getting in the way of another attempt. Neither requires the agent to use a special file-writing API.

Individual disk branches or checkpoints cannot yet be deleted, so the number of live branches needs planning even when losing results are no longer used. A branch is also not a security boundary: credentials cover the whole disk, so anyone who can mount it can reach every branch and checkpoint. Untrusted tenants need separate disks. Branching on Archil-managed disks is generally available, while branching on bring-your-own-bucket disks is an Enterprise feature.

Copy-on-write at the sandbox level: forking a running or stopped environment

Disk branching saves filesystem state, but an attempt may also need an execution environment, and Archil sandboxes have fork() for that layer. A fork of a running or paused sandbox resumes from the source’s CPU, memory, and disk state together. A fork of a stopped sandbox cold-boots from its disk, so it inherits files and installed packages but not running processes.

Forking a running sandbox briefly pauses it while the snapshot is taken, then resumes it, and attached process connections close. That makes it worth treating the base as a template rather than as a live environment doing unrelated work. For the prepare-once pattern, the documented route is to stop the prepared sandbox and fork from its disk state. There is no memory snapshot in this path, and the stopped base uses no compute while it waits.

Archil’s parallel agents guide shows this stopped-template workflow with three forks given different hints or models. The forks run in parallel, their results are scored, the fastest passing fork is promoted, and the rest are deleted. Extra mounted disks need particular care: a sandbox with additional disks must be stopped before it is forked, and every fork mounts the same disks, because only the root disk is branched. Sandbox forking is not branching every attached storage resource. Each running fork also bills for its own CPU and memory time. The worthwhile number of attempts depends on both the task and the speed of the fork operation.

How the research community is formalizing the same primitives

Research on operating systems and data systems also separates a shared starting point from exploration that each attempt does on its own. Fork, Explore, Commit (February 2026) introduces the branch context as a first-class OS abstraction. A branch context combines a copy-on-write filesystem view with a process group and a structured fork, explore, and commit lifecycle. Contexts can nest for hierarchical exploration, while first-commit-wins resolution governs competing siblings.

The paper’s userspace filesystem implementation, BranchFS, reports sub-350 µs branch creation independent of base filesystem size and under 1 ms commit overhead for small changes. Its proposed branch() Linux syscall would add kernel-enforced sibling isolation and reliable termination. Those results and proposals apply only to that research design and make no claims about Archil’s implementation. The connection is conceptual convergence on fast branching, isolated state, and an explicit end to an attempt. It is not a claim that Archil implements the paper’s mechanisms or shares its performance figures.

Chronos, (September 2026) looks at what happens when there is more than one storage layer. An agent’s logical state may span a filesystem, a relational database, and a NoSQL/vector database. If only one store is branched, the apparent isolation can fall apart when changes are merged. Chronos separates branch management from the data path within each store to provide atomic cross-store visibility for merges without modifying the underlying engines. That research validates the broader need for consistent branching while marking an important limit of filesystem and sandbox isolation.

Scoring attempts and deciding what to commit

A clean fork makes an attempt independent, but it does not make the result good. A reliable scoring signal turns parallel exploration into a selection process. Archil’s parallel agents guide scores attempts by tests passed and a benchmark result, and the fastest fork that passes all tests wins. Correctness acts as the gate, and performance decides among the passing attempts. This makes evaluation part of the workflow rather than something attached after the agents have finished.

The two main strategies serve different goals. First-wins commits the first attempt that passes a correctness gate and aborts the remaining forks, minimizing latency when any correct answer is acceptable. Best-of-N lets all attempts finish and commits the highest-scoring passing result, favoring quality when a reliable metric exists. An attempt can return a (success, score) tuple, and the orchestrator can then pick the highest score from the attempts that succeeded. A failed attempt can report its result without modifying the base.

The losing path matters just as much as the selection rule. Deleting a sandbox fork, or simply not mounting a disk branch, leaves the base and the other forks untouched. There is no rollback of losing edits because those edits stayed inside their own filesystem view. Not mounting a branch is not the same as deleting its stored resources. The disk-branch deletion limit still matters.

Where the pattern fits and where it does not

Fork-per-attempt pays off when approaches can run independently, correctness can be scored reliably, and rebuilding the base would take meaningful time. Trying bug fixes, code generation with different temperature settings, and multi-model comparison fit that pattern when there are several ways that might work. A test suite, benchmark, or linter can act as the automated gate that chooses among them.

By contrast, attempts that depend on the result of the previous attempt are inherently sequential. A human review gate does not gain the same benefit from automated parallel scoring, and a task with only one meaningful approach has little to explore. For tasks where a single well-prompted attempt usually succeeds, branching overhead is not worth it. N parallel forks cost N × (CPU + memory time), even if their disk branches are cheap to create.

The boundary of an attempt also has to include the state it can change. If an agent writes to both a disk branch and an external database, its database writes are not branched by the filesystem operation. A losing attempt’s database side effects must be rolled back by hand, or the database must have branching of its own. Chronos addresses that problem at the research level, but it is not a shipped product. Copy-on-write is a strong answer for independent attempts inside its isolation boundary, while side effects outside that boundary require separate cleanup.