# 0018: A World's PGlite cluster is prepared at image build

Status: Accepted. Date: 2026-10-07.

A World whose PostgreSQL is PGlite created its cluster on every fresh boot. A fresh `up` removes the
instance directory, so PGlite 0.5.8 found no `PG_VERSION` in the empty data directory. It then ran
initdb in a second wasm instance, dumped that cluster to a tar, unpacked the tar into the real data
directory and synced every file to disk (`PGlite#init`, the `initdb` branch). After that,
`pglite-host.mjs` opened `template1` to create the declared database and role, closed it, and opened
the declared database. In a browser tab every one of those file writes goes through the kernel. In
Rallly's run 19, engine-doors' profile put the PGlite realm at 2.2 s, about 0.85 s of it in write-heavy
file operations (writeFile, write, utimes, open and close on fresh files) on the data directory being
created.

PGlite has its own path for an existing cluster: when `PG_VERSION` is present it logs "found DB,
resuming" and starts Postgres on it. So the cluster is made once, where builds run, and the World's
boot opens it.

- `volter-world-infra prepare` (with `VOLTER_WORLD_CONFIG` naming the World) runs the host itself with
  `--prepare`. That is the same `openDeclaredDatabase` path a serving host takes: initdb, the
  declared database and role, then a clean `close()`. The output is
  `<World dir>/.volter-prepared/pglite-postgres-data`, and a stamp beside it names the runtime's
  version (its host is the open path that made the cluster), its exact `@electric-sql/pglite` pin
  (initdb's encoding and locale are PGlite's defaults; the host passes no initdb parameters), and the
  declared user and database. The password is not in the cluster. The role is created without one,
  and the host's gateway checks the declared password on each connection, so a World with another
  password opens the same cluster correctly. The open path creates no extension in the cluster: they
  are loaded into the module at each open. Nothing is reimplemented. The bytes are the ones the same
  wasm writes on a first boot.
- At `up`, an empty PGlite data directory takes the prepared cluster by rename (a copy across file
  systems). It does so only when the stamp matches. Otherwise it boots as before and names the
  mismatch in the host's log. The host log also records the placement. A host started on a placed
  cluster is passed `--prepared`, and it opens the declared database directly: the `template1`
  maintenance open, a whole second PGlite start, exists only to create that database and role, and
  the stamp vouches that they are there.
- The image build runs `prepare` on its host, after the World's packages are installed. The World's
  layer then carries `.volter-prepared` beside `world.json`, placed by reference as the World's
  packages are. That part belongs to browser-substrate's image builder.

A rename consumes the prepared cluster, so on a native machine only the first fresh boot after
`prepare` takes it, and later fresh boots initialize as they always did. A tab re-applies the World's
layer on each load. The seed is unchanged: stored data still arrives through the vendor's API after
`up`.

## Evidence

Unmeasured. The motivation is engine-doors' profile of Rallly run 19, relayed by the orchestrator.
Neither the preparation nor the opened boot has been run (owner ruling 2026-10-07: code only).
Thread B's Rallly run on this branch and on the image-builder branch gives the number.
