Back to Articles
Data Architecture

Database Branching: From Snapshots to Lakebase

LLM: How the database bracnhing works?

View as Markdown

A software branch is useful because it gives a developer a place to make a mistake without making that mistake everyone's problem. Databases have always made that promise harder to keep. Their state is large, mutable, shared by applications, and often sensitive. A schema migration can be versioned as code, but a meaningful test of it also needs data, roles, constraints, and application behavior. Database branching tries to make an isolated state cheap enough to create whenever the code changes. Its most important boundary is often missed: creating a branch is a storage operation; reconciling two independently changed databases is a semantic problem.

Where the idea began

The intellectual roots lie in three related but distinct lines of work. Database researchers studied how to preserve multiple versions of data so readers could see a consistent state while writers continued to change it. POSTGRES's early design also explored historical data and time travel; later work formalized snapshot isolation. These ideas made a database's past addressable, but a transaction snapshot is usually a read view with a bounded lifetime, not a durable, writable development environment. The distinction matters: preserving history answers what did the database look like?; branching adds what would happen if we changed that state independently? [1, 2]

Storage systems supplied another ingredient. Copy-on-write filesystems retain an old block and write a new block when data changes. A snapshot can therefore refer to existing blocks without copying every byte; a writable clone diverges only as writes occur. OpenZFS expresses this directly in snapshots and clones. Applying that technique to a live database still requires a transactionally consistent starting point, independent database execution, and safe management of logs and retention. Git supplied the workflow metaphor—branch, experiment, review—but not a ready-made storage engine for low-latency SQL queries or a universal rule for merging conflicting business records. [3, 4]

The initial operational answer was much less elegant: take a backup, dump and restore a database, or keep a shared staging database. These methods are still appropriate for many teams. Yet a full copy costs time and space in proportion to the data moved, while shared staging introduces interference between tests. The historical direction was therefore from copying bytes, to sharing unchanged storage, to treating isolated database state as an on-demand development primitive.

Timeline showing conceptual steps from historical views through copy-on-write clones and branch-oriented database products.

Figure 1. Conceptual evolution, not a claim that each product directly descended from every earlier one. Sources: [1–8].

Several approaches emerged, each solving a different problem

Approach What branches or copies How changes return Main strength and boundary
Dump/restore or backup restore A complete database at a chosen time Reapply migrations or manually transfer data Portable and familiar; copying and provisioning become expensive as data grows.
Storage-level copy-on-write clone, such as Aurora Database storage pages shared initially, then changed independently Normally a separate deployment or data movement process Fast test copy; clone management and product limits remain relevant. [5]
Schema-oriented branch, such as PlanetScale's deploy requests A development schema, with optional separate data copy depending on configuration Review and three-way comparison of schema changes before deployment Strong schema review; this is not a general merge of independently modified production rows. [6]
Version-controlled SQL data, such as Dolt Schema and rows in a versioned storage engine Diff and merge with conflict handling Suited to collaborative data editing; requires an engine designed for this model. [7]
Copy-on-write Postgres branch, such as Neon and Lakebase A point-in-time Postgres state that later diverges Apply reviewed migrations to target; branch reset discards child changes Excellent for disposable, realistic environments; branch changes do not automatically reconcile with parent. [8, 9]

These are not merely generations of one feature. Aurora made physical cloning practical for operational testing. PlanetScale treated schema evolution as a reviewable deployment problem. Dolt made row-level version control a first-class database concern, using a content-addressed tree designed for efficient difference calculation. Neon treated cheap, isolated Postgres environments as a consequence of separating compute from versioned storage. Databricks's Lakebase builds on that Neon architecture and embeds it in its platform. The choice among them depends on what the word branch must mean: a disposable experiment, a reviewed schema change, or a mergeable record of data edits. [5–9]

What Databricks Lakebase actually branches

Databricks announced Lakebase public preview in June 2025, describing it as a managed Postgres service built on Neon technology. The branching feature is therefore best understood as an extension of Neon's disaggregated Postgres architecture, rather than as Git transplanted into a standard Postgres server. The Postgres compute layer executes transactions and queries; a separate SafeKeeper service durably receives write-ahead log (WAL) records, while PageServer organizes data pages and history into non-overwriting layers backed by cloud object storage. A page can be reconstructed for a log sequence number (LSN), the position that identifies a point in the WAL history. Caches and page images keep ordinary reads from replaying an entire log. [8, 10, 11]

When a branch is created at a chosen state, it initially references the parent's existing data. Its subsequent WAL and page changes are stored separately. A read of an unchanged page can resolve through shared history; a changed page resolves through the branch's own history. Thus zero-copy describes branch creation, not zero storage forever. Each active branch also needs compute resources appropriate to its workload; shared storage does not mean that tests consume no compute. The parent can continue accepting writes, but those later writes do not flow automatically into a child created earlier. [8, 9]

Diagram of a parent branch and two child branches sharing the base state while retaining independent changes.

Figure 2. Simplified logical model of a Lakebase/Neon fork. The actual read path includes Postgres caches, PageServer layers, and object storage; arrows show logical visibility rather than a physical page copy. Sources: [8–11].

Consider an orders table at branch time T0. Production has 1,000 orders. A developer creates feature/discounts, adds a discount_code column there, and inserts a test order. Meanwhile production receives 20 real orders. The feature branch keeps its original starting state plus its own changes; it does not silently acquire those 20 new orders. To test against the latest parent, the developer can reset the child, but reset replaces the child's data and schema and loses its local changes. The reviewed ALTER TABLE belongs in a migration tracked with code and run against the intended target. Copying the feature branch over production would erase intervening production state; treating a reset as a merge would erase the experiment. Lakebase's tutorial accordingly promotes schema changes through migrations and uses reset for a fresh working branch. [9, 12, 13]

Diagram separating branch test, reviewed migration, and branch reset rather than implying a data merge.

Figure 3. The branch validates a proposed change; the deployment process applies the migration to the current target. A reset is a destructive replacement of child state, not a merge. Sources: [9, 12, 13].

When the model is useful

Per-developer and per-pull-request environments. Create a branch from a controlled parent, run migrations and integration tests against realistic shape and constraints, then delete it. Separate branches prevent tests and developers from changing one another's state. Automate creation, expiry, credentials, and cleanup; review production-like data access before copying sensitive rows into development. [9, 13]

Migration rehearsal. Test whether a proposed column, index, backfill, or constraint works against a representative state. The branch can reveal SQL failures, data-dependent constraint violations, and application incompatibility. It cannot prove a production migration will be safe under the target's later data, live concurrency, traffic, locks, and operational load. Rehearse the deployment procedure as well as the SQL.

Point-in-time investigation and recovery. Branch from a past state to inspect an incident without rolling back the active database. Recovery is a separate decision: Databricks's point-in-time restore creates a new root branch, and an application must deliberately switch its connection if that restored state should serve traffic. [14]

Agent and parallel experimentation. Give each coding agent or experimental workflow its own stateful sandbox so speculative SQL does not collide with another run. Isolation helps contain mistakes, but access controls, protected branches, sensitive-data policy, and resource limits still determine whether this is safe. [9, 15]

The tradeoff is conceptual as well as operational. Branching reduces the cost of divergence; it does not eliminate the cost of reconciliation. If the requirement is to merge different teams' edits to business rows into one authoritative state, evaluate a database with explicit data diff and merge semantics—or design that reconciliation in the application. If the requirement is to test and discard a stateful experiment, Lakebase's copy-on-write branch is a strong fit. The right question is not “does this database have Git-style branches?” but “which parts of Git's workflow are implemented, and where does responsibility for merging state begin?”

References

  1. Stonebraker and Rowe, The Design of POSTGRES, 1986.
  2. Berenson et al., A Critique of ANSI SQL Isolation Levels, snapshot isolation discussion.
  3. OpenZFS, Snapshots, Clones and Bookmarks.
  4. Neon, Deep Dive into Neon Storage Engine, 2023.
  5. AWS, Cloning a volume for an Amazon Aurora DB cluster.
  6. PlanetScale, Database branching: three-way merge for schema changes, 2023.
  7. Dolt, Architecture.
  8. Databricks, Announcing Lakebase Public Preview, June 2025.
  9. Databricks, Branches.
  10. Databricks, From monolith to Lakebase to LTAP, June 2026.
  11. Databricks, Object Storage + WAL: Lakebase Postgres for the agentic era, August 2026.
  12. Databricks, Manage branches.
  13. Databricks, Branch-based development workflow.
  14. Databricks, Point-in-time restore.
  15. Databricks, Database Branching: A Developer's Guide, 2026.