file_copy_method is a two-value enum with a wildly disproportionate payoff. One of its settings makes copying a database take about the same fraction of a second whether the database is one gigabyte or one terabyte. The other is the way PostgreSQL has always done it. The enum is new in PostgreSQL 18, and the interesting value is clone.

The default is copy, which does what it says: a straight physical, byte-for-byte duplication of the files. clone instead asks the operating system to share the blocks. On Linux it calls copy_file_range() and the filesystem’s reflink machinery; on macOS, copyfile(). The parameter governs the two operations that copy relation files wholesale, CREATE DATABASE when you ask for STRATEGY = FILE_COPY, and ALTER DATABASE ... SET TABLESPACE.

The reason clone is worth caring about is copy-on-write. On a filesystem that supports it, reflinking does not move any data; it writes a new set of metadata pointers at the same physical blocks and marks them shared, to be split apart only if and when one side is written. So the work is constant no matter how large the source is. People have measured cloning a 120 GB database in around 200 milliseconds and an 800 GB one in just over half a second. That is what turns CREATE DATABASE from a copy you schedule around into an instant one, and it is what finally makes throwaway per-branch and per-developer databases practical rather than aspirational.

The catch is a short stack of preconditions, and all three have to hold. First, the filesystem has to do copy-on-write: XFS with reflinks, which modern XFS enables by default, or Btrfs, ZFS, or APFS. On ext4 there is nothing to reflink, and clone on a filesystem that cannot do it fails rather than silently falling back to a copy, which is easy to walk into inside a container image that quietly defaults to ext4. Second, you have to request STRATEGY = FILE_COPY explicitly, because since PostgreSQL 15 the default is WAL_LOG, which reproduces the template block by block through the WAL and never touches the file-copy path this parameter controls. Third, the template database can have no sessions connected while it is copied, an old requirement of FILE_COPY that used to be a real imposition and, now that the copy takes a few hundred milliseconds, mostly is not.

So this is one of the uncommon settings where leaving the default is the wrong instinct when the conditions are right. On a copy-on-write filesystem, cloning databases, file_copy_method = clone is as close to free as storage operations get: terminate the template’s connections, create with STRATEGY FILE_COPY, and a terabyte lands in the time a rounding error takes. Off such a filesystem it does nothing for you at all, which is the entire guide to when to reach for it.