Skip to main content
An agent that works on a database is only half copied by fork: the fork gets the agent’s disk, but DATABASE_URL still points at the same database, so two forks would write over each other. Give each fork a Neon branch, an instant copy-on-write copy of the database, and the copy is complete: files, packages, the agent’s memory, and its data. Now you can try a task three ways at once, compare what each attempt did to the data, keep the best one, and throw the rest away.
Paste this into your coding agent

fork-agent: this guide as a working app

Everything on this page, runnable: create an agent with its own Neon project, chat data into it, try a task several ways, compare the branches side by side with one query, and keep the winner. Hono and @neon/sdk on the server, React from a CDN in the browser, no build step. Add both keys, npm start.

What a fork copies

The fork also inherits the source’s env, which is the one thing you change: point DATABASE_URL at the fork’s own branch, and the two halves line up. Branching needs a Neon account and an API key (the examples here use @neon/sdk, Neon’s official TypeScript SDK); an unclaimed Claimable Neon project cannot create branches.
1

Give the agent its own database

Create a Neon project for the agent with the Neon SDK, then create the instance with the project’s connection string in env. Record the Neon ids in metadata, which is readable, so your server can find each instance’s branch later without a database of its own:
node
With throwOnError: true a failed call throws a typed error (kind is api, not_found, auth, rate_limit, and so on) instead of returning { data, error }. The agent reads DATABASE_URL from its shell like any other variable. Chat some data into it before you fork, for example “Create a products table with 30 products, some with duplicate names and messy categories.”
2

Copy the database and the computer

For each attempt, take both copies at the same moment: a Neon branch of the agent’s branch, and a fork of the agent’s instance.
node
branch is { branch, endpoint, connectionString }. A new branch keeps its parent’s roles and passwords, so before the reset, an attempt could write to the original just by pointing its credentials at the agent’s endpoint host. The reset changes the password on the branch only: the agent’s own credentials keep working on its branch and stop working on the attempt’s. Creating several branches off one parent at once can briefly lock the project (423); the SDK retries that for you. If one half fails, delete the half that succeeded.Auto-sleep counts only traffic on the fork’s URLs, not the agent’s own calls out to its model, so a long idle timeout keeps a fork from sleeping mid-attempt. Polling the fork’s sessions (the next steps) counts as traffic, so an attempt you are watching stays awake.
3

Repoint the fork at its branch

A fork inherits the source’s env and ignores an env field in the fork body, so set the fork’s DATABASE_URL with PATCH /v1/instances/{id}, record its branch in metadata, and restart the fork to load the new value:
node
A fork always starts running, even from a stopped source, so it boots once with the agent’s DATABASE_URL before the restart. The agent does not touch the database until you send it a turn, so that is harmless. A service your image starts at boot is different: until the restart, anything it writes lands in the agent’s database, so keep such services off on forks until they have their own DATABASE_URL. A fork of a large instance can return 202 with the fork provisioning: poll GET /v1/instances/{id} until it reads running before you patch it.Run the attempts in parallel: branching and forking three times at once, including the restarts, takes about half a minute.
4

Send each fork the task

Wait for the fork’s gateway (GET /v1/health on its instance URL returns ok: true), then send the task. The turn does not need your connection: open it with stream: true, read the first event, response.created, keep its session_id, and close the stream. The turn keeps running on the fork.
node
Follow each attempt with GET /v1/sessions/{id}: while active_response_id is set the attempt is working, and once it is null the last assistant message in history is its answer. Tell each fork which attempt it is in the task, and ask the later ones to take a different approach from the obvious one, so you get real alternatives to compare.
5

Compare the branches

Every attempt changed its own branch, and the agent’s branch is untouched. Run the same query on all of them to see the difference. The SDK gives you any branch’s connection string, and a READ ONLY transaction over Neon’s HTTP driver means the comparison can’t write to any of them:
node
A write in the check, such as delete from products, fails with cannot execute DELETE in a read-only transaction.
6

Keep the best one

Keeping an attempt makes it the agent. Delete the other forks and their branches, delete the original instance, and point the project’s default branch at the winner. Deleting the original instance is permanent, everything on its disk included; take a backup first if you might want it back, and say so plainly in your confirm dialog:
node
Then relabel the winner’s metadata as the agent. Send the whole object you want, with attempt-only keys set to null. The original’s branch stays in Neon as the point the round started from: Neon refuses to delete a branch that has children, or a project’s root branch. To throw a round away instead, delete every fork and its branch and leave the agent as it was.

Worth knowing

  • Fork between turns. Fork copies the disk and a branch copies the data at the moment of each call. If the agent is in the middle of a turn, the two copies can disagree, so start a round while the agent is idle (active_response_id is null on its sessions).
  • Each attempt is a full instance. It counts against your workspace’s instance limit and bills compute and managed spend like any other until you delete it. Before the first top-up a workspace holds three instances in total, so a round of attempts beside the agent needs a funded workspace.
  • Processes do not carry over. The fork boots fresh with the same files; anything the agent had running starts again only if ~/.agent37/hooks/post-restart.sh starts it.
  • Credentials on disk come along. Anything the agent keeps in its own files, and any connected messaging channel’s bot token, is in every fork. Disconnect channels on agents you plan to fork.
  • Branches are cheap. A branch shares its parent’s storage until it diverges, and its compute scales to zero when idle. See Neon branching.