mockgres
In-memory Postgres-compatible engine for tests.
Table of Contents
- Overview
- Quickstart
- Running
- Testing
- Features
- Limitations
- Architecture Notes
- Roadmap
- Contributing
- License
Overview
Mockgres was born out of my frustration for the Postgres docker container taking too long, in my opinion, to start up. I didn't want to have to write mocks, but I also wanted my unit tests to run as fast as possible. I also didn't want to have to manage local installations and cleaning up in between test runs.
Mockgres aims to replicate a reasonable subset of Postgres functionality and semantics for two use cases.
The first use case is that of a typical CRUD app. The second use case is for a basic task queue using SELECT FOR UPDATE SKIP LOCKED.
Quickstart
- Prereqs: Rust toolchain,
cargo. cargo run -p mockgres --bin mockgres -- 127.0.0.1:6543psql -h 127.0.0.1 -p 6543 postgres
Running
Currently, all you really need to do is specify MOCKGRES_ADDR.
You can technically run it by embedding it as a library, all you really need to do is what's specified in main.
Testing
- Commands:
cargo fmt --allcargo clippy --workspace --all-targets -- -D warningscargo test --workspaceTesting covered pretty much exclusively by integration tests in thetestsdirectory.
Features
- Supported SQL surface (SELECT/INSERT/UPDATE/DELETE, joins, ON CONFLICT, etc.).
- PG wire protocol compatibility expectations.
- Locking semantics (FOR UPDATE, SKIP LOCKED).
- Copy-on-write snapshots via
mockgres_freeze()and per-sessionmockgres_reset(). - Type support basics.
What's supported
- Core SQL: SELECT/INSERT/UPDATE/DELETE, WHERE/ORDER BY/LIMIT/OFFSET, projections/aliases, aggregates (count/sum/avg/min/max), GROUP BY/HAVING, simple scalar functions (now/current_timestamp/current_date/upper/lower/length/coalesce/abs/log/ln/greatest/extract epoch), type casts, interval literals, expressions
- Joins: CROSS/INNER/LEFT with ON predicates, multi-join, subqueries IN (SELECT ...)
- DML: INSERT ... ON CONFLICT DO NOTHING/DO UPDATE, UPDATE ... FROM, RETURNING
- Locking and tx: BEGIN/COMMIT/ROLLBACK (read committed only), SELECT FOR UPDATE SKIP LOCKED
- Copy-on-write snapshots: global freeze + per-session sandboxes (
mockgres_freeze(),mockgres_reset()) - types: int4/int8, float8, text/varchar, bool, date, timestamp/tz, bytea, interval, JSONB (no json ops though)
- Constraints/indices: primary key, unique, foreign key (cascade), create/drop index supported but no-op
- Catalog: schemas, databases (create and drop not supported), table create/drop, ALTER TABLE,
pg_catalog.pg_namespace,pg_catalog.pg_typeseeded for builtin types - Wire protocol: simple and extended protocol
Copy-on-write snapshots
- Freeze the current database state with
SELECT mockgres_freeze();. The first call captures a base snapshot; subsequent calls are no-ops and returntrue. - After freezing, every new session gets its own copy-on-write sandbox cloned from the frozen base. Changes made in one session stay isolated from others.
- Reset a pooled/reused connection with
SELECT mockgres_reset();to discard that session’s sandbox and reclone from the frozen base on next use. - Works in both simple and extended protocols, so it is safe to use with connection pools (run
mockgres_reset()at the start of each test when reusing a pooled client).
Example (psql):
-- Seed baseline and freeze
create table items(id int primary key, label text);
insert into items values (1, 'a');
select mockgres_freeze(); -- returns t
-- Session A (shared DB) mutates baseline
insert into items values (2, 'b');
-- Session B (new connection) gets isolated sandbox
insert into items values (3, 'c');
select id from items order by id; -- sees 1,3 (not Session A’s 2)
-- Reset Session B sandbox (e.g., between tests)
select mockgres_reset(); -- returns t
select id from items order by id; -- back to frozen base: 1
Architecture Notes
tbd
Roadmap
Aims to be compatible with at least 1-2 most recent versions of Postgres.
Contributing
tbd
License
MIT