Concepts
Lifecycle
Decide which process owns initialization, startup, delayed shutdown, and deletion of the temporary PostgreSQL container.
pg-tmp separates the public container root from the actual PostgreSQL cluster:
/tmp/pg_tmp.xxxxxx/
NEW
initdb.log
stop.log
data/
PG_VERSION
postgresql.conf
postgres.log
The root directory is the value returned as dataDir. PostgreSQL owns the
data/ directory. PG_VERSION inside that directory is the compatibility check
used when start() looks for a prewarmed cluster.
Initialization
initdb() creates the root container and initializes data/ for temporary use:
import { initdb } from '@pg-nano/pg-tmp'
const dataDir = await initdb()
The cluster is configured for speed over durability. It uses trust authentication, disables fsync-related durability settings, writes logs inside the container, and listens on a Unix socket by default.
Calling initdb() on a root that already has data/PG_VERSION throws instead
of reusing the existing cluster.
Startup
start() does not require a prior initdb() call:
import { start } from '@pg-nano/pg-tmp'
const pg = await start()
When dataDir is omitted, start() first scans os.tmpdir() for compatible
pg_tmp.* roots with a NEW marker. If it claims one, startup can skip
initialization. If none exists, it initializes a fresh root.
After claiming or creating a root, start() begins initializing another root in
the background. That prewarmed root is available to a later start() call.
Shutdown
There are two shutdown paths:
| Path | Owner | Cleanup |
|---|---|---|
await pg.stop() |
Current process | Stops Postgres and removes the root unless keep is true. |
timeout > 0 |
Background stopper | Waits for active test connections, then stops and removes the root unless keep is true. |
Use manual shutdown for tests where the process has a clear finally block:
import { start } from '@pg-nano/pg-tmp'
const pg = await start({ timeout: 0 })
try {
await runTests(pg.dsn)
} finally {
await pg.stop()
}
Use background shutdown for scripts that hand a DSN to another process and then exit:
import { start } from '@pg-nano/pg-tmp'
const pg = await start({
timeout: 60,
})
console.log(pg.dsn)
If active connections remain when the timeout expires, the background stopper keeps waiting and checks again on the same interval.