Anchor cuts a new branch from your production database in 1.4 seconds using copy-on-write storage. Test migrations, run integration suites, and tear it down when the PR merges — no shared staging, no cleanup scripts.
Anchor is one binary, one Helm chart, or a managed endpoint. Branch from prod, run your suite, share a connection string, throw it away.
Every branch ships with a JDBC string, a psql REPL, and a web playground that shows EXPLAIN + execution plan inline.
-- avg ticket size for cohorts that hit 3DS SELECT c.cohort_month, AVG(o.amount_cents) / 100.0 AS avg_usd FROM orders o JOIN customers c ON c.id = o.customer_id WHERE o.three_ds_status = 'challenged' AND o.created_at >= '2026-01-01' GROUP BY c.cohort_month ORDER BY c.cohort_month;
Generated from your live branch vs. main, not from the SQL file.
Anchor runs your migration suite, records lock contention, and rejects PRs that would block.
# .github/workflows/ci.yml - uses: anchor-hq/branch@v3 with: from: main ttl: "4h" label: pr-${{ github.event.pull_request.number }}
RBAC scoped per branch with environment-level allowlists. Prod branches require a second approver for write access.
Every PR opens a branch from the latest WAL position. We re-run your migration in a sandbox with the same indexes, the same row counts, and the same FKs. Locks that would stall prod show up as a red gate on the PR.
CoW storage means a 200GB branch costs less than the wifi at your offsite. Bring your own AWS / GCP / Azure on Scale.
For weekend projects and one-person teams.
For teams running a real Postgres against a real product.
For 2TB+ databases and regulated workloads.
"We retired our staging environment four months ago. Every PR gets a 1.4-second branch off prod. Cleanup is automatic when the PR closes."
"Anchor caught two ACCESS EXCLUSIVE locks last quarter that would have taken our checkout down. The PR-blocking is opinionated and we love it."
"Our pgvector index is 184GB. Branching used to be a half-day operation. Anchor does it in 2.1s. I still don't fully believe it."
Our team is largely ex-Postgres and ex-CockroachDB. If you have a deeper question, drop us a line at [email protected].
We store every Postgres page in a content-addressed object store. A branch is a manifest: an ordered list of page hashes per relation. Branching is a manifest fork — O(relation count), not O(rows). When you write to a branch, the new page gets a new hash and replaces the entry; the original page stays referenced by main. Storage is shared until divergence.
P50 1.4s, P95 2.1s, P99 3.4s — measured across our managed fleet over the last 30 days. The first query after create can be slower if the relevant pages aren't on the host's local cache; we pre-warm the buffer cache for the top 200 relations by size, which covers most real workloads.
Yes — pgvector, PostGIS, TimescaleDB, citus, pg_stat_statements, and 38 other extensions are pre-built into the branch image. We track upstream releases within 72 hours. For custom extensions, you can supply a build script and we'll bake it into your workspace image.
We branch at a logical WAL position, not a physical snapshot — so an in-flight transaction on main doesn't pin our cut. If you want point-in-time semantics, pass --at-lsn or a recent timestamp; we'll resolve it to the nearest WAL boundary that has no open writes touching the relations you specify.
Hard limit is 64 levels. In practice nobody goes past 4. Branches of branches share storage with their grandparent, so you can demo a customer-specific bug fix off a colleague's PR without doubling the storage cost.
Connect your Postgres in 90 seconds. The first three branches are on us, forever.