~/postgresql-sandboxes/
On this box: PG 16.5 · 17.1 · 17.2 · 17.4 · 18.3 —
pg_sandbox --version → v1.0.1
deploy → connect → load data → inspect → destroy
export PGS_BIN_DIR=/opt/postgresql/18.3
cd ~/postgresql-sandboxes
pg_sandbox deploy -s pg18
pg_sandbox status -s pg18
pg_sandbox use -s pg18 -- -c "SELECT version();"
pg_sandbox run -s pg18 -- pgbench -i # -d auto-injected
pg_sandbox run -s pg18 -- pgbench -T 3 # ~6k tps locally
pg_sandbox config show -s pg18 # KEY / VALUE / SOURCE
pg_sandbox destroy -s pg18 --force
One binary wraps initdb, pg_ctl, psql and every client — connection params injected for you.
A primary and an async standby on its own port — then promote.
pg_sandbox deploy -s primary
pg_sandbox deploy -s standby1 \
--replicate-from primary --slot primary_standby1_slot
sleep 2
pg_sandbox status -s primary # replicas[0]=walreceiver state=streaming
pg_sandbox use -s primary -- -c "CREATE TABLE t(id int); INSERT INTO t VALUES (1);"
pg_sandbox use -s standby1 -- -c "SELECT * FROM t;" # → the row, replicated
pg_sandbox promote -s standby1 # standby1 role → primary
pg_sandbox destroy -s standby1 --force
pg_sandbox destroy -s primary --force
Replica gets its own port automatically. status reports live write/flush/replay lag.
A whole primary + N-standby topology, managed as a unit.
pg_sandbox cluster deploy -s rep -N 2 # rep_p + rep_s1 + rep_s2
sleep 2
pg_sandbox cluster status -s rep # primary shows BOTH replicas streaming
pg_sandbox global_status # grouped fleet view
pg_sandbox cluster destroy -s rep --force # tears down all 3 members
Members auto-named rep_p / rep_s1 / rep_s2, ports 65432–65434.
--sync-count is accepted but currently deferred (still async today).
Table-level pub/sub across major versions — the classic upgrade path.
pg_sandbox deploy -s pub -b /opt/postgresql/17.4 # publisher on PG 17
pg_sandbox use -s pub -- -c "CREATE TABLE t(id int primary key); INSERT INTO t VALUES (1);"
pg_sandbox publish -s pub --pub-name my_pub --all-tables # auto wal_level=logical + restart
pg_sandbox deploy -s sub -b /opt/postgresql/18.3 # subscriber on PG 18
pg_sandbox subscribe -s sub --from pub --pub-name my_pub --copy-schema
sleep 2
pg_sandbox use -s sub -- -c "SELECT * FROM t;" # → the row, replicated
pg_sandbox destroy -s sub --force
pg_sandbox destroy -s pub --force
Per-sandbox -b picks the major. publish raises wal_level=logical & restarts for you; --copy-schema dumps the schema from 17 into 18 first.
Turn a captured out.txt into an HTML diagnostics report.
# capture from any sandbox, then render
pg_sandbox use -s pg18 -- -X -f "$GATHER/gather.sql" > out.txt
pg_sandbox report --pg-gather-dir "$GATHER" \
--input ~/postgresql-sandboxes/out.txt \
--output ~/postgresql-sandboxes/gather.html
open ~/postgresql-sandboxes/gather.html
Auto-resolves bin-dir; ingests the dump in a throwaway sandbox that then self-destructs. Input is pre-scanned — psql meta-commands in a hostile out.txt are rejected.
Also: global_status (fleet view) ·
build <ver> (compile from source) — everything reproducible & disposable.