Branches
Copy-on-write Postgres branches in Kisenon — fork-at-LSN, lifecycle, and cascade.
A branch is a pointer to a Log Sequence Number (LSN) in the project's storage. Creating one is an O(1) row insert; it does not copy data. Branches diverge as you write to them, and only the delta is stored.
The model
Every project has a main branch from creation. From main (or any
existing branch) you can fork a new branch:
- At HEAD — the new branch starts from the parent's current LSN.
- At a specific LSN — the new branch starts from a historical LSN within the parent's WAL retention window. This is the "time-travel" case: you can branch off a point in the past as long as the WAL is still retained.
Reads on a branch fall through to the parent's pages until the branch diverges. Writes record only the delta. The result:
- A 100 GB project with ten small branches is billed as ~100 GB total.
- Spawning a branch is sub-second.
- Branches are disposable. Run a destructive migration, throw the branch away, the parent is untouched.
Naming
Branch names are user-visible labels, scoped to the parent project. Constraints match project names:
- 1–63 characters.
^[a-zA-Z][a-zA-Z0-9_-]*$.- Unique within the project.
The internal branch id (br_<24 hex>) is the stable reference. Use
the id, not the name, when scripting against the API; names can be
renamed.
State machine
A branch transitions through:
creating → ready → deleting → deleted- creating — control plane is registering the branch with the pageserver tenant. Typically sub-second; longer if the pageserver is under load.
- ready — branch can be attached to endpoints and accept writes.
- deleting — cascade in progress: every endpoint on this branch is being stopped and removed.
- deleted — terminal. The row is retained for auditability for a short period, then garbage-collected.
The CLI shows the current state for every branch:
keon branches list --project <project-id>Create
keon branches create --project <project-id> --name my-feature --parent mainTo branch at a historical LSN, pass --parent-lsn <lsn>:
keon branches create \
--project <project-id> \
--name pre-migration \
--parent main \
--parent-lsn 0/1A2B3C4DThe LSN must be within the project's WAL retention window. If it has been compacted past, the branch creation fails.
Delete
Deleting a branch cascades to every endpoint attached to it:
- All endpoints on the branch are stopped and removed.
- The branch itself is torn down.
- Storage is reclaimed asynchronously by pageserver compaction.
keon branches delete <branch-id>You cannot delete the main branch of a project — delete the project
instead. You can delete any other branch even if it has children;
in that case the children are reparented to the deleted branch's
parent at the deletion LSN.