Anchor
v3.1 · Postgres 16 + pgvector

Branch your Postgres like Git. Stage every PR against real data.

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.

$ npx anchor branch create --from main
anchor / acme-prod · 14 branches
live
branch
rowsstoragecreatedauthor
main prod
14,208,402284 GBsystem
feat/checkout-rev2 staging
14,208,6121.4 GB ·CoW32s agom.tobin
stripe-3ds-test PR #4128
14,208,612402 MB4m agop.anand
fix/migration-031 tests pass
14,208,40261 MB11m agoh.suzuki
spike/pgvector-rerank dev
14,208,4028.2 GB1h agoy.abara
eu-dpa-shard-cut 3 conflicts
14,208,402184 MB3h agoi.calderon
showing 5 of 14 branches + new branch · 1.4s
acme-prod · today
live
Active branches
14
+3 since Mon
Avg create time
1.42 s
P95 2.1s
Storage saved via CoW
3.84 TB
99.3% dedupe
Migrations passing
28 / 31
3 blocked on lock
Branches over time 7d
region: us-east-1 · eu-central-1 PG 16.4
Branching Postgres in production at
Halcyon QUARTERMAST ATRIUM Stratos Pavilion beacon/ Spool Lighthouse Halcyon QUARTERMAST ATRIUM Stratos Pavilion beacon/ Spool Lighthouse
Capabilities

Everything you wanted from staging. Without the cleanup.

Anchor is one binary, one Helm chart, or a managed endpoint. Branch from prod, run your suite, share a connection string, throw it away.

Branch playground

Run a real query against a real branch.

Every branch ships with a JDBC string, a psql REPL, and a web playground that shows EXPLAIN + execution plan inline.

branch: feat/checkout-rev2 · 14,208,612 rows EXPLAIN ANALYZE · 41ms
-- 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;
cohort_monthavg_usd
2026-01142.08
2026-02138.41
2026-03156.22
2026-04161.94
Schema diff

See exactly what the migration touches.

Generated from your live branch vs. main, not from the SQL file.

CREATE INDEX orders_customer_idx ON orders(customer_id)
+ CREATE INDEX CONCURRENTLY orders_customer_status_idx
~ orders.three_ds_status: text → enum (4 variants)
Migration runner

Test every migration. Against full prod.

Anchor runs your migration suite, records lock contention, and rejects PRs that would block.

026_add_3ds_columns214ms
027_backfill_status4.1s
028_drop_legacy_col61ms
029_create_enum2ms
× 030_alter_ordersACCESS EXCL
git → branch

A branch per PR. Auto.

# .github/workflows/ci.yml
- uses: anchor-hq/branch@v3
  with:
    from: main
    ttl: "4h"
    label: pr-${{ github.event.pull_request.number }}
Roles

Devs branch. Reviewers approve. Auditors read.

RBAC scoped per branch with environment-level allowlists. Prod branches require a second approver for write access.

developer
branch.* / read.prod
reviewer
approve / merge
auditor
read.audit_log
14d
Median lifetime
2h 14m
↘ −38m / 14d
Migrations tested
418
96.4% passed
Cold-start P95
2.10 s
incl. pgvector load
Branch lifetime distribution 418 branches
<15m1h4h12h1d3d+
Migration safety net

Catch the lock before production does.

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.

  • Lock-graph capture: ACCESS EXCLUSIVE, SHARE ROW EXCLUSIVE, and table-rewrite detection.
  • Replay the last 72 hours of prod write traffic against the branch — pre-merge.
  • Index plan delta: did the planner pick the new index? See the row count.
  • Extension support: pgvector, PostGIS, TimescaleDB, citus — all branch-safe.
Read the safe-migration guide
Pricing

Per branch. Not per seat.

CoW storage means a 200GB branch costs less than the wifi at your offsite. Bring your own AWS / GCP / Azure on Scale.

Hobby

free forever
$0
/ month

For weekend projects and one-person teams.

  • 3 concurrent branches
  • 500 MB CoW storage / branch
  • GitHub PR integration
  • Community Slack
Start free
Most popular

Team

per seat
$29
/ seat · month · annual

For teams running a real Postgres against a real product.

  • 50 concurrent branches
  • 100 GB CoW storage / branch
  • Role-based access · 4 roles
  • Migration safety gates on PR
  • SLA: branch create P95 < 2.4s
Start 14-day trial

Scale

BYOC
$249
/ month base · usage on top

For 2TB+ databases and regulated workloads.

  • Unlimited concurrent branches
  • Self-hosted in your VPC
  • Signed audit log · SOC 2 + SSO
  • Solution architect · 99.99% SLA
Talk to sales
Customers

Backend teams who deleted their shared staging and never looked back.

"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."
YA
Yusuf Abara
CTO · Mercury
"Anchor caught two ACCESS EXCLUSIVE locks last quarter that would have taken our checkout down. The PR-blocking is opinionated and we love it."
IC
Ines Calderón
Head of Engineering · Brightwave
"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."
PA
Priya Anand
Staff Engineer · Linnea
FAQ

Frequently asked, honestly answered.

Our team is largely ex-Postgres and ex-CockroachDB. If you have a deeper question, drop us a line at [email protected].

How does copy-on-write storage actually work under the hood? +

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.

What's the cold-start time on a new branch? +

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.

Does it support Postgres extensions like pgvector? +

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.

How do you handle long-running transactions during branch cut? +

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.

What's the maximum branch tree depth? +

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.

1.4s · branch from main

Cut a branch. Merge with confidence.

Connect your Postgres in 90 seconds. The first three branches are on us, forever.