# Runtime and Performance Notes
`pglite-oxide` runs the upstream PGlite WASI runtime inside Wasmtime. It does
not link a native Postgres library.
## WASI Layout
The embedded backend uses the same shared-memory CMA protocol as upstream
PGlite. The host preopens:
- `/tmp` as the runtime root
- `/tmp/pglite/base` as the Postgres data directory
- `/home` for runtime home files
- `/dev` for small device shims such as `urandom`
Opening an existing cluster still invokes PGlite's `initdb` export because the
WASM runtime uses that entry point for in-memory backend setup too. Existing data
is preserved; the full cluster creation work is avoided once `PG_VERSION`
exists.
## Startup Cost
The first instance in a process can take a while because Wasmtime prepares the
large PGlite WASM module and starts the embedded backend.
`pglite-oxide` reduces startup cost in four ways:
- compiled modules are cached in process, so additional `Pglite` instances avoid
the same compile work
- compiled modules are serialized to a `.cwasm` cache keyed by the PGlite WASM
SHA-256, Wasmtime major version, target, and config id
- fresh clusters are created from a bundled prepopulated PGDATA template before
the backend session starts
- `Pglite::temporary()` clones a process-local template cluster, so later
temporary databases copy a prepared filesystem
Use `Pglite::builder().fresh_temporary().open()?` only when a test specifically
needs fresh cluster initialization.
## Persistent Compile Cache
The crate keeps Wasmtime's persistent cache feature enabled and also writes a
crate-owned `.cwasm` cache under the platform cache directory. Cache writes are
best effort; if the cache cannot be read or written, the module is compiled
normally and the app continues.
For fast local test loops in a downstream workspace, add the same profile
override used by this repository. Wasmtime's debug cache otherwise keys entries
by the rebuilt test binary mtime, which defeats reuse after ordinary edits:
```toml
[profile.dev.package.wasmtime-internal-cache]
debug-assertions = false
```
For larger suites, prefer reusing one `Pglite` instance per test when isolation
allows it, and use `fresh_temporary` only for initialization-specific coverage.
## Socket Server Limits
`PgliteServer` is deliberately blocking and handles one frontend connection at a
time against a single embedded backend. It refuses SSL/GSS negotiation requests
with the standard PostgreSQL `N` response; connection URIs generated by the
crate include `sslmode=disable`.
Set SQLx, `tokio-postgres`, Diesel, or framework pools to one connection.
## Proxy Utility
Expose a persistent database over TCP:
```sh
cargo run --bin pglite-proxy -- --root ./.pglite --tcp 127.0.0.1:5432
psql 'postgresql://postgres@127.0.0.1:5432/template1?sslmode=disable'
```
On Unix systems, the default proxy mode is `/tmp/.s.PGSQL.5432`:
```sh
cargo run --bin pglite-proxy
PGPASSWORD=postgres psql 'postgresql://postgres@/template1?host=/tmp'
```
## Runtime Assets
Runtime asset provenance is tracked in [ASSETS.md](ASSETS.md). The crate bundles
the PGlite runtime files needed to start the embedded backend.