Embedded Postgres for Rust tests and local apps.
Real PostgreSQL. Instant testing. Packaged runtime. Direct Rust API or a local Postgres URL.
Usage · Performance · Extensions · Dump & Upgrade · Testing · Tauri
pglite-oxide brings PGlite/Postgres to Rust with a small API. Open a database
directly with Pglite, or hand PgliteServer to SQLx and any standard
Postgres client. The packaged runtime is PostgreSQL 17.5. No local Postgres
install, no Docker, no runtime build toolchain.
Already using SQLx or another Postgres client? Add the crate and point your client at an embedded database URL:
cargo add pglite-oxideuse pglite_oxide::PgliteServer;
use sqlx::{Connection, Row};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let server = PgliteServer::temporary_tcp()?;
// For a persistent TCP server:
// let server = PgliteServer::builder().path("./.pglite").start()?;
let mut conn = sqlx::PgConnection::connect(&server.database_url()).await?;
let row = sqlx::query("SELECT $1::int4 + 1 AS answer")
.bind(41_i32)
.fetch_one(&mut conn)
.await?;
assert_eq!(row.try_get::<i32, _>("answer")?, 42);
conn.close().await?;
server.shutdown()?;
Ok(())
}That's it. Real PostgreSQL, no service setup.
Postgres should be as easy to add to a Rust project as SQLite.
- ⚡ No service tax: no Docker, no local Postgres, no testcontainers.
- 🔌 Use your real stack: SQLx,
tokio-postgres, CLIs, and other clients connect through a normal local URL. - 🌉 Proxy included: expose an embedded database to non-Rust tools with
pglite-proxy. - 🧪 Clean tests: temporary databases are isolated, fast, and removed on drop.
- 💾 Persistent apps: keep local app data across restarts when you want it.
- 🧩 Extensions included:
pgvector,pg_trgm,hstore,citext, and more. - 📦 Portable dumps: use bundled
pg_dumpfor logical backups and upgrade paths. - 🚀 Near-native feel: close to native Postgres, fully embedded.
Current local snapshot on Apple M1 Pro, 16 GB RAM, and macOS 26.4.1.
Full numbers and reproduction steps live in the
performance guide. Lower is better.
| Operation | native pg + SQLx | pglite-oxide + SQLx | vanilla PGlite + SQLx |
|---|---|---|---|
| 25,000 INSERTs in one transaction | 132.36 ms | 149.54 ms | 257.02 ms |
| 25,000 INSERTs in one statement | 46.14 ms | 59.39 ms | 117.19 ms |
| 25,000 INSERTs into an indexed table | 188.72 ms | 253.38 ms | 352.64 ms |
| 5,000 indexed SELECTs | 81.39 ms | 125.31 ms | 203.05 ms |
| 25,000 indexed UPDATEs | 351.05 ms | 578.96 ms | 720.63 ms |
pglite-oxide stays close to native Postgres while running entirely embedded
and consistently performs better than vanilla PGlite.
Bundled extensions are supported, including pgvector, pg_trgm, hstore,
citext, ltree, and more. See the
extensions guide
for the full catalog and usage details.
use pglite_oxide::{extensions, PgliteServer};
use sqlx::Connection;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let server = PgliteServer::builder()
.path("./.pglite")
.extension(extensions::VECTOR)
.start()?;
let mut conn = sqlx::PgConnection::connect(&server.database_url()).await?;
sqlx::query("CREATE TABLE IF NOT EXISTS items (embedding vector(3))")
.execute(&mut conn)
.await?;
sqlx::query("INSERT INTO items VALUES ('[1,2,3]')")
.execute(&mut conn)
.await?;
conn.close().await?;
server.shutdown()?;
Ok(())
}