A database per git worktree that barely uses any disk space
- Name
- Dennis Paagman
- @djfpaagman
I’ve been using git worktrees a lot lately. Having a couple of branches checked out next to each other (often with an agent working away in one of them) is awesome. Until two of them start running migrations against the same development database and everything gets mixed up.
The obvious fix is to give every worktree its own database. But I like to develop against an anonymized copy of production, and copying gigabytes of data for every new worktree is slow and fills up my disk in no time.
Postgres 18 quietly shipped a new setting that fixes both: file_copy_method = clone. It’s been there since 18.0 (changelog), so if you’re still on an older version, that’s a good reason to upgrade.
What it does
Postgres has always been able to create a new database from a template. By default it copies the whole database, which takes a while for a big database and doubles the disk space you use.
With file_copy_method = clone, Postgres asks the filesystem to clone the files instead. On a copy-on-write filesystem (APFS on any recent Mac, or Btrfs, XFS or ZFS on Linux) the new database points to the exact same blocks on disk as the template. Only the pages you change get written to new blocks.
That means a new copy of your database:
- uses almost no extra disk space, it only grows as it starts to differ from the template.
- is really fast to create, no matter how big your database is.
Perfect for a big anonymized production copy!
Setting it up
Enable it once:
ALTER SYSTEM SET file_copy_method = 'clone';
SELECT pg_reload_conf();
Then create your database with the FILE_COPY strategy. The default strategy (WAL_LOG) ignores the new setting, so you need to ask for it explicitly:
CREATE DATABASE myapp_feature_x
TEMPLATE myapp_template
STRATEGY = FILE_COPY;
Or from the command line:
createdb --template=myapp_template --strategy=file_copy myapp_feature_x
One catch: Postgres refuses to use a database as a template while something is connected to it. So I keep a separate myapp_template database with the production copy that nothing ever connects to, and clone from that.
That’s it. Every worktree gets its own database with realistic data, in seconds, without filling up your disk. Run destructive migrations, mess up your data, try something weird. When you’re done, just drop it and clone a fresh one ✨.
I've got some availability for new clients! If you're looking for someone with 15 years of Rails experience and a deep feel for Hotwire, who's all in on building with AI agents, let's chat.
Get in touch