Harsh Vardhan Goswami
Jul 4, 2025
Managing database schema changes has long been one of the trickiest—and riskiest—parts of running your own Postgres, whether it’s in a Docker container, a cloud VM, or a managed service. Downtime, table locks, and painful rollbacks are all too common with traditional migration tools, especially when your application demands high availability. Enter pgroll: an open-source CLI tool designed to bring zero-downtime, fully reversible migrations to any Postgres deployment. In this guide, we’ll show you how pgroll lets you evolve your database schema safely and confidently—no matter where your database lives.
Database schema changes are a fact of life for any growing application. But if you’re running your own Postgres—whether in Docker, on a VM, or using a managed cloud database—schema migrations can be risky. Traditional migration tools often lock tables, cause downtime, and make rollbacks a nightmare. For teams that need high availability, this simply isn’t good enough.
pgroll
is an open-source CLI tool that brings zero-downtime, reversible schema migrations to any Postgres instance, no matter where it runs. This guide will show you how to use pgroll for safe, continuous database changes—without service interruptions or lock-induced headaches.
What is pgroll?
pgroll is a purpose-built migration tool for Postgres that enables you to:
Apply schema changes without downtime or table locks
Instantly roll back in-progress migrations if something goes wrong
Let old and new schema versions coexist, so you can upgrade apps at your own pace
pgroll achieves this by using the expand/contract migration pattern and managing multiple schema versions under the hood. It’s a single Go binary, works with any Postgres 14+ instance (including RDS, Aurora, DigitalOcean, GCP, or your own containers), and requires no special extensions or plugins.
Why Not Use Traditional Migration Tools?
Classic migration tools (like Flyway, Liquibase, or plain SQL scripts) often:
Acquire
ACCESS EXCLUSIVE
locks, blocking reads/writes during DDLRequire downtime windows and careful coordination
Make rollbacks hard—often requiring a full DB restore
Don’t support phased rollouts or canary deployments
pgroll solves these problems by:
Never locking tables for long periods
Allowing both old and new schema versions to be used at the same time
Making rollbacks instant and safe, even after a migration has started
How pgroll Works
pgroll uses the expand/contract pattern, but automates all the complexity for you:
Expand: Only backward-compatible changes are applied first (e.g., adding nullable columns, helper columns for backfills, etc.).
Multi-version: Both the old and new schema versions are available as Postgres schemas (with views mapping to the same underlying tables).
Contract: Once your new app version is live, pgroll finalizes the migration, cleans up old columns/constraints, and removes the old schema version.
Rollback: You can revert to the previous schema version at any time before completing the migration.
This means you can deploy new app versions that use the new schema, while old app versions continue to work—no downtime, no dual-write hacks in your codebase
Getting Started with pgroll
Prerequisites
A running Postgres database (anywhere: Docker, VM, or managed service)
pgroll CLI installed (see below)
Step 1: Install pgroll
For most Linux/macOS systems, download the prebuilt binary:
Or use Homebrew on macOS:
Or build from source:
Step 2: Initialize pgroll on Your Database
pgroll needs a dedicated schema (default: pgroll
) to store its state. Run:
This works for any Postgres instance—local, cloud, or containerized
Running Your First Migration
Step 3: Define a Migration
Write your desired schema state in a YAML or JSON file. Example: creating a users
table.
migrations/01_create_users.yaml
Step 4: Start the Migration
For the first migration, you can use
--complete
to apply everything in one go.For breaking changes, you’ll use a two-phase workflow (see below).
Example: Zero-Downtime Breaking Change
Suppose you want to make description
NOT NULL—a classic breaking change.
migrations/02_make_description_not_null.yaml
Start the migration (expand phase):
pgroll will:
Create a helper column and backfill it safely, without blocking writes
Set up triggers to keep both columns in sync
Expose a new schema version with the updated column
Deploy your new app version to use the new schema (see next section).
Complete the migration (contract phase):
If you need to roll back before completion:
How to Use Multiple Schema Versions in Your App
pgroll creates versioned schemas (e.g., public_01_initial
, public_02_make_description_not_null
) with views that map to the real tables. To target a specific schema version, set the search_path
in your database connection.
Example: Node.js (pg)
Get the latest schema version:
Update your app’s config or deployment to use this schema version for phased rollouts.
Integrating with CI/CD and ORMs
Use
pgroll
in your deployment pipelines to automate migrations.Generate migration files from your ORM’s SQL output, then convert them to pgroll format if needed.
Always review generated migrations for breaking changes and backfill logic.
lightbulb_2
Pro tip
Best Practices for Self-Hosted and Managed Postgres
Back up your database before major migrations.
Monitor: Use pgroll’s logs and your DB monitoring to track migration progress.
Automate: Add pgroll commands to your CI/CD for repeatable, safe deployments.
Test: Use a staging environment with a copy of production data to validate migrations.
Conclusion
pgroll brings zero-downtime, reversible schema migrations to any Postgres deployment—self-hosted, containerized, or managed. By automating the expand/contract pattern and supporting multiple schema versions, you can deploy database changes safely, roll back instantly, and keep your applications online.
If you run Postgres anywhere, pgroll is a must-have for modern, continuous delivery.
Resources:
Written for engineers who run Postgres in the real world—whether that’s on Docker, VMs, or the cloud. If you have questions or want to share your setup, let us know in the comments or join the pgroll community!