Skip to content

How It Works

pgbranch leverages PostgreSQL’s built-in template database feature to create instant, efficient snapshots of your database state.

PostgreSQL has a powerful feature called template databases. When you create a new database, you can specify an existing database as a template:

CREATE DATABASE new_db TEMPLATE existing_db;

This creates a copy of existing_db as new_db. The key benefits:

  • Fast - PostgreSQL copies the database at the filesystem level
  • Efficient - Uses copy-on-write on supported filesystems
  • Complete - Includes all tables, data, indexes, functions, etc.

When you run pgbranch commands, here’s what happens under the hood:

  1. Terminates all connections to the working database
  2. Creates a template database: CREATE DATABASE pgbranch_<name> TEMPLATE myapp_dev
  3. Records branch metadata (creation time, parent branch, etc.)
Working DB: myapp_dev
┌───────────────────┐
│ CREATE DATABASE │
│ pgbranch_main │
│ TEMPLATE myapp_dev│
└───────────────────┘
Template: pgbranch_main (snapshot)
  1. Terminates all connections to the working database
  2. Drops the current working database
  3. Creates a new working database from the target branch’s template
  4. Updates the current branch pointer
Working DB: myapp_dev Template: pgbranch_feature
(will be dropped) (source for restore)
│ │
▼ │
DROP DATABASE │
myapp_dev │
│ │
└──────────┬───────────────────┘
┌────────────────────────────┐
│ CREATE DATABASE myapp_dev │
│ TEMPLATE pgbranch_feature │
└────────────────────────────┘
Working DB: myapp_dev (restored from feature)

pgbranch creates template databases with a specific naming pattern:

pgbranch_<branch_name>_<project_hash>

For example:

  • pgbranch_main_a1b2c3
  • pgbranch_feature_auth_a1b2c3

The project hash ensures multiple projects can use pgbranch without conflicts.

Branch metadata is stored in .pgbranch/ in your project root:

.pgbranch/
├── config.json # Database connection, remotes
├── branches/ # Branch metadata
│ ├── main.json
│ └── feature.json
└── key # Encryption key (not committed)

The actual database snapshots are PostgreSQL databases on your server. You can see them:

Terminal window
psql -c "SELECT datname FROM pg_database WHERE datname LIKE 'pgbranch_%'"
OperationTypical Time
Create branch< 1 second
Checkout branch1-5 seconds
Delete branch< 1 second

Times depend on database size and disk speed, but are generally very fast due to template database efficiency.

Each branch consumes disk space equal to the database size at the time of snapshot. However:

  • PostgreSQL uses copy-on-write on supported filesystems (ZFS, Btrfs)
  • Identical data blocks are shared between databases
  • Space usage grows as branches diverge

To create or restore a database from a template, PostgreSQL requires no active connections. pgbranch automatically terminates connections, but this means:

  • Active queries will be cancelled
  • Transactions will be rolled back
  • Applications connected to the database will disconnect

Template databases are local to a PostgreSQL instance. To share branches across machines, use remote storage.

Each branch is a complete database snapshot. You cannot:

  • Snapshot individual tables
  • Create incremental backups
  • Branch specific schemas only
ApproachSpeedDisk UsageData Included
pgbranchFastDatabase sizeComplete
pg_dump/restoreSlowCompressedComplete
Schema-only migrationsFastMinimalSchema only
Docker volumesMediumContainer sizeComplete

pgbranch is ideal when you need complete database snapshots (including data) with fast switching during development.