The real thing
PostgreSQL 18.3 compiled to WebAssembly and translated to Go. Your SQL, planner behaviour and error codes are PostgreSQL’s, not an emulator’s.
The same schema, queries and per-test isolation, measured on one machine against the official image with docker run, Testcontainers, and a devbox-installed PostgreSQL.
Medians from 5 runs on one machine. Docker and Testcontainers memory uses 3 fresh OrbStack runs. Bars scale to the largest value in each card; lower is better.
From command start to TCP SELECT 1; downloads are excluded and Devbox uses an initialized cluster.
Median time to create an isolated database copy and run a join.
Warm indexed SELECT over TCP.
Median time to sort and count 200k rows.
After setup, before queries. Docker and Testcontainers sum container usage (PostgreSQL, plus Ryuk for Testcontainers) and benchmark-process growth. OrbStack VM changes are reported separately.
Same MB scale; Go link growth, compressed image layers, and devbox cache download measure different things.
Query latency, methodology and how to reproduce are on the benchmarks page.
The real thing
PostgreSQL 18.3 compiled to WebAssembly and translated to Go. Your SQL, planner behaviour and error codes are PostgreSQL’s, not an emulator’s.
Nothing to install
One dependency per language. No Docker daemon, no container runtime on CI, no files written to disk.
Share reads, isolate writes
Run migrations and seed data once, then share a fork across read-only tests and give writing tests isolated copies. Writing tests can run in parallel.
Any driver
pgmem listens on the PostgreSQL wire protocol, so pgx, psycopg, JDBC, node-postgres, ORMs and migration tools work unchanged.
s, err := pgmem.Start(ctx, pgmem.Options{Database: "app"})if err != nil { t.Fatal(err)}defer s.Close()db, _ := sql.Open("pgx", s.DSN())import pgmem, psycopg
with pgmem.start(database="app") as pg: with psycopg.connect(pg.template.dsn) as conn: conn.execute("SELECT 1")try (Pgmem pg = Pgmem.builder().database("app").start(); Connection conn = DriverManager.getConnection(pg.template().jdbcUrl())) { conn.createStatement().execute("SELECT 1");}import { PgmemServer } from '@pgmem/core';import pg from 'pg';
await using server = await PgmemServer.start({ database: 'app' });const client = new pg.Client({ connectionString: server.url });