Branches
Fork a branch at its latest cell, keep your loaded data and fitted models, and run several ideas side by side.
A Clusy branch is not a Git branch. It's an experiment branch inside a notebook, and the thing that makes it useful is that forking keeps your kernel state.
One notebook, forked at the last shared cell: three arms run side by side on their own kernels, and come back as a single comparison.The problem it solves
You're partway through a notebook. You've loaded some data, cleaned it, built features, a chunk of compute now sitting in memory. Now you want to compare two models. In a plain notebook you'd duplicate a pile of cells and hope they don't drift, or comment things in and out and lose track of which result came from which setup.
Branching handles this. You fork where the two ideas split, the new branch opens with everything already in memory, and the original branch is untouched.
How a fork works
Hover the gap under the branch's last cell. The insert strip appears, and next to Code and Markdown there's a Branch button.
Everything that happens next happens inside the sandbox you're already running. Clusy copies the parent kernel's namespace into a fresh kernel for the new branch, and gives the branch its own view of the workspace files. Nothing is uploaded, nothing is written to durable storage, and none of the cells above the fork run a second time — so df, X_train and anything else you'd already computed are simply there when the branch opens.
That's the whole immediate cost of a fork. It is a local copy, which is why forking is quick and does not write saved-state storage or add a checkpoint step to your run. The branch can consume saved-state storage later, when the project reaches a durability boundary.
Forking copies the kernel into the new branch: everything the cells above the fork left in memory is already there, so not one of them runs a second time.The new branch starts with no cells of its own; the first one you write can use the inherited state right away. The original branch keeps running on its own kernel and doesn't notice.
You fork from the tip, not from history
A fork copies the kernel as it is right now, so it can only be cut from the branch's latest cell. Try to fork from a cell further up and Clusy stops you:
Forking an earlier cell would copy the branch's current live state, not the state at that cell. Fork from the latest cell instead.
This is the honest version of a tempting feature. There's no per-cell history of your kernel, so a fork from cell 3 of a 20-cell branch would silently hand you the state as of cell 20 while looking like it gave you cell 3 — comparisons built on that would be quietly wrong. If you need to branch from an earlier point, run the notebook to that point on a new branch first.
A fork is also refused when the parent isn't in a clean state to copy — an empty parent branch, unresolved control cells, or code cells that have been edited since they last ran. In each case Clusy names what to fix. Run the stale cells, resolve the controls, then fork.
Forking doesn't save your work
A fork copies state within the running sandbox. It does not write a durable copy of it. Your branches are saved when the project reaches a durability boundary — everyone leaves, or you change the sandbox and choose Transfer state — and not on the branching path itself.
That's deliberate: it's what keeps forking instant. The one case it costs you is an abrupt sandbox loss before any boundary, where a branch can come back without its state. It then says so plainly rather than pretending, and turns view-only.
How many branches you can run at once
Branches are capped per project, and the cap is a hard limit: Clusy refuses the branch rather than quietly discarding another branch's state to make room.
| Runtime | Concurrent branches | Live kernels |
|---|---|---|
| CPU | 3 | 4 (the primary branch plus 3) |
| GPU | 8 | 9 (the primary branch plus 8) |
Ask for one more than that, by hand or through the agent, and you get a Branch limit reached dialog:
CPU sandboxes support up to 3 concurrent branches (GPU: 8). Delete a branch to create another.
Deleting a branch is what frees a slot — and only deleting. The count is every branch in the project that hasn't been deleted, regardless of its current status. It also counts across the whole project, not per notebook: three branches in one notebook and one in another is four.
Two consequences worth knowing before you hit them:
- A GPU project that drops to CPU can end up over the cap. Eight branches are legal on a GPU and only three are on CPU, so after the downgrade the extra branches can't be opened until you delete some. Nothing is lost by the downgrade itself; the branches just won't materialize while you're over the limit.
- The agent hits the same wall you do. A branched experiment that asks for five variants on a CPU sandbox is refused at the cap, not trimmed to fit. A single experiment tops out at 8 variants in any case, and the whole batch is refused as one — you never get a half-created sweep.
Branches run in parallel
Each branch has its own kernel, so branches genuinely run at the same time rather than taking turns. Three variants training at once is three kernels working concurrently in one sandbox — which is what the cap above is really protecting, since they all share that sandbox's CPU and RAM.
Each branch also gets its own view of the workspace files, so a variant that writes model.pkl doesn't overwrite the model.pkl its sibling wrote.
What a fork doesn't carry
Forking is cheap, but it isn't magic, and it's better to know the edges before you hit them.
- Some live objects don't survive. A branch copy serializes the namespace, so open file handles, live database connections, CUDA and other device contexts, an
np.loadhandle you never closed, and some OpenCV or Torch internals are left out. The rest of the namespace still makes it across; those specific names just won't exist on the new branch. Re-create them in the branch's first cell. - A failed namespace copy aborts the fork. If Clusy cannot establish the child kernel and copy the usable state, it rolls the attempted child back instead of publishing an empty branch that looks comparable. Fix or rebuild the problematic state, then retry the fork.
If a branch needs something heavy and unpicklable, load it inside the branch rather than upstream of the fork.
Cells above a fork become read-only
The moment you fork at a cell, that cell and everything above it on the parent branch are shared history: every branch below depends on having run exactly those cells. Editing them after the fact would silently change what each branch was built on, so Clusy freezes them instead. Try it and the cell tells you:
This cell is part of shared branch history. Edit the mutable suffix or create a new fork instead.
The cells after the fork point on the parent stay editable, and that's usually where you want to be working anyway. If you need to change something in the frozen prefix, fork again from the cell above it and make the change on the new branch.
When a branch loses its state
A branch's variables live in its kernel inside the sandbox. If that state is gone before it could be saved — an abrupt sandbox loss with no durability boundary in between — the branch comes back view-only rather than pretending its kernel is intact:
This branch's kernel state is unavailable (it was lost before it could be saved). It is view-only: navigation, export, and explicit leaf deletion remain available, but editing, running, reordering, inserting, and forking are disabled.
You can still read it, export it, and delete it. You can't run it. This is the honest failure mode of instant forking, and the reason durability boundaries matter: leave a project normally and your branches are saved with it.
Branch status
Each branch carries a status indicator so you can see what it is doing:
| Status | Meaning |
|---|---|
initializing | Being created; briefly read-only |
active | You're working on it |
running | Cells on it are executing right now |
error | Its last run failed |
dormant | Not currently active |
completed | Finished |
deleted | Removed |
These are lifecycle and activity indicators, not filing controls. Deleting is the only user action that frees a branch slot.
Deleting a branch discards its cells and its kernel state, so Clusy asks you to confirm. The primary branch can never be deleted, and a branch with forks of its own asks you to delete its child forks first. If you delete the active non-primary branch from the fork selector, Clusy switches away before removing it.
Where branches show up
Once you've branched, the notebook isn't a straight list anymore: branches share their early cells and then diverge. The canvas still shows you one thread at a time, which is the readable thing to do.
- The notebook renders the active branch, top to bottom.
- At the cell a fork was cut from, a fork selector appears inline: a pill for each fork off that cell, plus a
+to cut another. Click a pill to follow that fork. - The branch control at the top right of the canvas shows the active branch and the branch count, and switches branches from anywhere in the notebook.
There is no separate tree or map view. The branch graph is a concept you hold in your head (and see in these diagrams); the UI navigates it one thread at a time.
Batch experiments
You don't have to fork by hand one branch at a time. Ask the agent to compare several variants ("try learning rates 0.1, 0.01, and 0.001") and it can run a branched experiment: it forks a branch per variant from the same starting state, runs them in parallel, and reports back in chat with a comparison table and a chip for each branch, so you can jump straight to any of them.
While it works, a placeholder appears inline at the fork point and tells you which phase it's in — preparing the isolated branches, creating the variant cells, then how many variants have settled — so a sweep that takes a few minutes isn't a blank canvas.
Read the comparison table carefully:
- The quickest clean run gets a neutral Fastest badge. That's a stopwatch, not a verdict. In an accuracy sweep the fastest arm is usually the worst model, because it's the one with the fewest epochs or the smallest config.
- A variant that failed never carries the badge; it keeps its error dot.
Nothing in the card decides which variant won. Reading the result is still your job.
A sweep costs N times as much
A branched experiment runs your work once per variant. On a CPU runtime with Auto, that path is unmetered on a paid plan and consumes the allowance on Free. On a GPU, five variants do roughly five times the compute, and the sandbox meter runs the whole time. Check the variant count before you sweep on a GPU, and remember the cap — a CPU sandbox will refuse the fourth variant outright.
Bringing branches back together
When you've decided which approach won, you converge. Ask the agent to converge the branches, and the cell they rejoin gets a bar across the top showing how many variants feed it and a chip for each.
Convergence records where experiment branches rejoin, which branch inputs were considered, and how the decision is presented. Each branch keeps its own variables and files.Converging records the decision — it doesn't merge state
This is the thing to be clear about. A convergence point marks where branches rejoin in the notebook, so the record shows which experiment fed the work below it. It does not merge kernel variables, files, or data: nothing from the losing branches moves, and nothing from the winner is copied into another kernel.
To actually carry on from the winning branch, work on that branch. Its variables are already there.
A convergence point can only be recorded on the branch's parent or another branch it descends from — not on a sibling, and not on itself, because a join has to point back to shared history to mean anything.
Converging then seals the lineage that feeds the join. A converged branch tells you to clear its convergence before changing or rerunning its source lineage, which stops you rewriting the history a recorded decision was based on. Clear the convergence, make your change, converge again.
Branches vs. Git
Clusy branches hold live kernel state and exist only in Clusy, so use them to explore. Git versions the notebook files, so use it to keep history. They work together: branch freely, then commit what's worth keeping.
The Branching experiments guide walks through a full comparison, with code.