- Durability off. Crash recovery is abandoned by contract: if the machine dies, you delete the data directory and start over. In exchange, every commit returns without waiting on disk.
- Memory-first storage with graceful spill. Data lives in RAM as much as possible and spills to disk only under memory pressure — without the hard capacity cliff of a ramdisk.
- Near-instant per-test databases.
CREATE DATABASE ... TEMPLATE tplcompletes in milliseconds via copy-on-write file clones, regardless of how large your seeded template is.
Test mode is a launch profile, not a fork of the engine. Your tests exercise the exact same binary and the same code paths as production — the whole point of testing against real Pgrust instead of a mock. The only differences are configuration knobs PostgreSQL itself documents as non-durable settings, plus a filesystem choice.
How it works
Test mode is three independent layers. Each is useful on its own; together they compound:Layer 1: the non-durable preset
Save this astest.conf and include it when starting the server:
test.conf
include line in postgresql.conf, or directly from your harness:
Layer 2: in-memory storage without a ramdisk
You might reach fortmpfs here — don’t. tmpfs has no copy-on-write clone support (which would defeat layer 3), and a ramdisk hard-caps at its allocation, so “spilling to disk” means swap thrashing.
The key insight: once fsync is off, an ordinary on-disk filesystem already behaves like an in-memory filesystem with disk spill. Every write lands in the kernel page cache and returns immediately; writeback happens lazily in the background, and only memory pressure forces pages out. Reads of recently written test data are cache hits. That is exactly “in memory as much as possible, spill to disk when needed” — implemented by the kernel, with no capacity cliff.
So layer 2 is just a filesystem choice:
- macOS
- Linux
Nothing to do. APFS — the default filesystem — supports copy-on-write clones natively and already satisfies both properties. Put your test data directory anywhere.
Layer 3: instant template clones
Withfile_copy_method = clone, CREATE DATABASE ... TEMPLATE ... STRATEGY FILE_COPY clones the template’s relation files with copy-on-write:
- On macOS, via
copyfile(..., COPYFILE_CLONE_FORCE)on APFS. - On Linux, via
copy_file_range(), which reflinks on XFS (reflink=1) and btrfs.
WAL_LOG strategy takes tens of seconds.
Putting it together: a test harness recipe
1
Once per suite: create the cluster and seed a template
tpl once seeding finishes.2
Per test: clone, run, drop
TRUNCATE sweeps or transaction-rollback tricks — and therefore no restrictions on what the test may do.3
On any crash: recreate, don't recover
If the server or machine crashes, delete the data directory and re-run the suite setup (or restore a cached copy of the post-initdb directory). Never rely on crash recovery of a test-mode cluster.
Expected performance
- Template clone: ~1–10 ms for typical test schemas, and roughly constant in template size on a reflink-capable filesystem — cloning is O(number of files), not O(bytes).
- Residual per-test cost: two cheap internal checkpoints that
FILE_COPYrequires (single-digit milliseconds atshared_buffers = 128MBon an idle test instance) plus connection establishment. - If clone latency ever dominates your suite, the standard mitigation is a warm pool of pre-cloned databases maintained by the harness (the IntegreSQL pattern) — Pgrust needs no changes to support it.
FAQ
Is test-mode Pgrust behaviorally different from production Pgrust?
Is test-mode Pgrust behaviorally different from production Pgrust?
No. Test mode changes configuration only — the same settings PostgreSQL documents as non-durable settings, plus
file_copy_method and two noise-reduction knobs. Query execution, WAL, checkpointing, and crash-handling code are identical to a production launch. What changes is the durability contract, not the engine.Why not just use tmpfs?
Why not just use tmpfs?
Two reasons: tmpfs cannot reflink, so copy-on-write clones degrade to full copies, and a ramdisk’s fixed allocation turns “spill to disk” into swap thrashing. With
fsync = off, a normal filesystem’s page cache gives you the in-memory behavior for free, with graceful writeback under pressure.Does this work in CI containers?
Does this work in CI containers?
Yes. The loopback-image recipe needs only
mount privileges (a privileged container or a host-prepared mount). If you can’t get a reflink filesystem in CI, everything still works on ext4/overlayfs — clones become fast in-kernel copies, so you lose the O(1)-in-template-size property but keep all the durability and memory-first behavior.Can I use test mode with the Docker image?
Can I use test mode with the Docker image?
Yes — pass the preset as flags or mount a
test.conf and add -c include=... to the container command. See Run Pgrust with Docker for how configuration is passed. For the copy-on-write clone path, the data volume must live on a reflink-capable filesystem (APFS/XFS/btrfs on the host).