Guides
Getting started
Quarry moves data between databases while both stay online. This guide installs the CLI and runs a first migration, start to finish.
What Quarry is
Quarry is a command-line tool for online database migrations. It copies every table from a source database to a target, then keeps the target in step by replaying the source’s change log until you switch over. Your application keeps reading and writing the source the whole time; the only pause is the cut-over itself, which usually takes a few seconds.
It is built for the moves that are hard to schedule downtime for:
- Upgrading to a new major version of PostgreSQL or MySQL.
- Moving a database to a new host, region or provider.
- Splitting one large database into several smaller ones.
Quarry reads the source through its replication stream and writes to the target with ordinary SQL, so there is nothing to install on either server. Every copy is resumable: if the process stops, quarry run --resume carries on from the last committed batch.
Install Quarry
Quarry is a single binary with no runtime dependencies. On macOS or Linux, install it with Homebrew:
brew install quarry-data/tap/quarry
Or use the install script, which downloads the release for your platform and puts quarry in /usr/local/bin:
curl -fsSL https://quarry.example/install.sh | sh
Check that the binary is on your PATH:
quarry --version
quarry 2.4.1 (build 5c1e9a2, 2 September 2026)
Note
Quarry connects to the source as a user that can read every table and open a replication connection. On PostgreSQL that is a role with the REPLICATION attribute. Troubleshooting lists the errors you see without it.
Your first migration
This walk-through moves a database called shop from a PostgreSQL 13 server to a new PostgreSQL 16 server. It takes four steps, and nothing is written anywhere until the last one.
-
Describe the source and target
In an empty directory, run
quarry initwith both connection strings. It writes them toquarry.toml, which later commands read.Terminalquarry init \ --source postgres://quarry@db-old.internal:5432/shop \ --target postgres://quarry@db-new.internal:5432/shopPasswords are never written to the file. Quarry reads them from
QUARRY_SOURCE_PASSWORDandQUARRY_TARGET_PASSWORDwhen it runs, soquarry.tomlis safe to keep in version control. -
Review the plan
quarry planconnects to both databases, compares their schemas and prints what it will copy. It writes nothing.Terminalquarry plan Plan for shop (PostgreSQL 13.14 → 16.4) TABLE ROWS SIZE STRATEGY orders 18,204,511 41.2 GB parallel, 8 ranges order_items 52,930,047 27.9 GB parallel, 8 ranges customers 1,204,332 1.1 GB single range products 84,210 96.0 MB single range 4 tables · 70.3 GB · estimated copy time 1 h 52 minTables missing on the target are created by
quarry run. If a table exists on both sides with different columns, the plan stops with an error before anything is copied. -
Rehearse with a dry run
A dry run checks permissions on both sides, confirms that the source can stream its changes, and times a sample batch from each table. A dry run changes nothing.
Terminalquarry run --dry-runThe report ends with safe to run or with the errors to fix first. Dry runs explains every line of it.
-
Run the migration and cut over
Start the migration. Quarry copies every table, catches up on the writes that arrived during the copy, and then keeps replaying new writes until you cut over.
Terminalquarry runIn a second terminal,
quarry status --watchshows the phase and the replication lag. Once the lag stays under a second, switch your application to the target:Terminalquarry cutoverCut-over blocks writes on the source, waits for the last changes to reach the target, and runs your switch-over hook. Writes pause only for that window, typically two to five seconds.
Next steps
- How a migration runs explains the four phases and what each needs from your databases.
- Rolling back a migration shows how to return to the source after a cut-over.
- The CLI reference lists every command and option.