Instant Postgres branching

Create isolated Postgres branches in seconds using copy-on-write storage. Each branch gets independent compute and scales to zero when idle.

Why branching?

Shared staging breaks when development runs in parallel

Pull requests, deployment previews, CI runs, and coding agents often change schema and data at the same time. When they share a staging database, those changes collide, tests become unpredictable, and one workflow can break another.

Modern development needs a different model: isolated databases that are created when work begins, run independently, and disappear when the work is done.

Shared staging databases

  • A few long-lived databases shared across the team

  • Changes interfere with concurrent workflows

  • Tests depend on data left by previous runs

  • Schema changes require coordination

  • Staging gradually drifts from production

A branch for every workflow

  • One isolated database for each PR, preview, test run, or agent

  • Created on demand when work begins

  • Kept only for as long as the workflow needs it

  • Runs independently from every other branch

  • Removed when the workflow ends

A branch for every workflow
Branching replaces a few shared staging databases with many isolated, short-lived databases, one for every workflow.

What is database branching?

Create a new, isolated Postgres branch from an existing database in two seconds, regardless of its size. Because Xata separates compute from copy-on-write storage, the branch starts with the parent’s schema and production-like data without copying the full database, then changes independently.

  • Instant creation

    Create a branch in two seconds, no matter how large the parent database is.

  • Production-like data

    Start with the parent’s schema and production-like data from the moment it is created.

  • Copy-on-write storage

    Share unchanged data with the parent and store only the blocks that change.

  • Fully independent

    Change schema and data without affecting the parent or any other branch.

How teams use branching

  • Pull requests

    Create a database branch for every PR. Test code against real data before merging.

  • Preview environments

    Give every deployment its own database with real data, no shared staging, no conflicts.

  • CI & testing

    Start every test run from a clean database. No drift, no flaky tests.

  • Debugging production issues

    Reproduce bugs on a production-like branch without touching live data.

  • Agents & automation

    Give every agent its own database. Run in parallel, without multiplying costs.

How copy-on-write branching works

Xata implements data branching at the storage layer. This makes branching extremely fast, even for terabytes of data.

1

Initial state

In the initial state, we start with a single branch, the parent branch. The volume associated with this branch is mounted on the PostgreSQL instance. The data is organized into blocks (numbered 1 to 8 in the diagram) and an index is used to keep track of the blocks.

2

Creating a new branch

When a new database branch is created, initially only the index is copied. The new child branch references the same data blocks as the parent branch. This is why branching is so fast regardless of the size of the branch, because no significant amount of data is copied at this stage.

3

Copy only modified blocks

As writes are received by either the parent branch or the child branch, only the modified blocks are copied. Each branch then references its own copy of those blocks. In the diagram, this has happened for blocks 3 and 6, resulting in significant disk space savings.

Branch-native Postgres
Xata separates Postgres compute from copy-on-write storage, so branching is built into the architecture rather than added on top of traditional database copies.
Scale to zero & wake-up

Pay for active branches, not idle environments

Xata branches scale compute to zero when idle and wake automatically when work resumes.

  • Scale to zero

    Idle branches stop consuming compute while their data remains available.

  • Instant wake-up

    Branches resume on first connection, with no manual provisioning.

Automate every branch

Create a branch automatically as each workflow starts, and remove it when the work is done.

1

Pull request opens

A developer opens a pull request.

2

Create a database branch automatically

The Xata GitHub App creates an isolated database branch for the pull request.

3

Run tests and previews

Connect CI jobs, migrations, and preview deployments to the branch.

4

Delete the branch when the pull request closes

The Xata GitHub App removes the database branch automatically when the pull request is merged or closed.

A branch for every pull request
Use the Xata GitHub App to create and manage a database branch automatically when a pull request opens, or use GitHub Actions to customize branch creation, configuration, and cleanup inside your existing CI workflow.
How to get started

Adopt Xata without moving production.

Keep production where it is, or move it to Xata. Either way, every pull request and deployment preview gets its own isolated Postgres branch.

Path 01

Keep prod where it is

Create a clone of your production database in Xata, keep it in sync with production, and have it ready for instant branching.

  • Branches from a production clone
  • Production data with built-in anonymization
  • Continuously synced with production
Create a production clone
Path 02

Run production on Xata

Run your production database on Xata with native branching, built-in high availability, read replicas, and automatic scale-to-zero.

  • Native branches from production
  • High availability
  • Read replicas
Create a production database

Give every workflow its own Postgres

Create isolated, production-like branches for every pull request, deployment preview, and coding agent.