PostgreSQL lets you clone a 6GB database in 212 milliseconds instead of 67 seconds. Here’s how…
Cloning databases comes in handy in a few situations:
- testing migration without touching prod data
- spinning up fresh copies for each test suite run
- resetting sandbox env between sessions
- reproducible snapshots for debugging
When your database is a few megabytes, pg_dump works fine. With hundreds of gigabytes, “just make a copy” becomes a serious bottleneck.
PostgreSQL has always had a templating system. Every CREATE DATABASE quietly clones template1 behind the scenes, and you can replace template1 with any database. (wrote about it earlier in one of my posts)
Version 15 introduced the STRATEGY parameter, switching to WAL_LOG by default (block-by-block copy via Write-Ahead Log). Smoother I/O, but slower for large databases.
PostgreSQL 18 has an option file_copy_method = clone. On modern filesystems like XFS, ZFS, or APFS, this leverages the FICLONE operation. Instead of copying bytes, the file system creates new metadata that points to the same physical blocks. Both databases share identical storage until you write something.
Here, the supported File System is doing the magic, which creates a copy-on-write (CoW) clone of a file.
When we update a row, the filesystem triggers copy-on-write only for the affected pages. The rest stays shared. 6GB clone takes zero additional space initially and grows only as data diverges.
One thing to keep in mind: the source database can’t have active connections during cloning. This is a PostgreSQL limitation, not a filesystem one.
Pretty neat!