🦀 RustMemDB
The logic-first, in-memory SQL engine designed for high-performance testing and rapid prototyping.
"Postgres is for production. SQLite is for files. RustMemDB is for code."
📖 Table of Contents
- ⚡ Why RustMemDB?
- 🚀 Killer Feature: Instant Forking
- 📊 Benchmarks
- ✅ SQL Support Matrix
- 🧩 Extensibility & Plugins
- 🎯 Ideal Use Cases
- 👩💻 Developer Experience (DX)
- 🛡️ Safety & Reliability
- 🔌 The "Drop-In" Architecture
- 💾 Persistence & Durability
- 🧩 Extensibility & Plugins
- ⚙️ Engineering Internals
- ❓ FAQ
- 📦 Installation
📚 Documentation
⚡ Why RustMemDB?
Integration testing in Rust usually forces a painful tradeoff:
- Mocking: Fast, but fake. You aren't testing SQL logic.
- SQLite: Fast, but typeless and behaves differently than Postgres/MySQL.
- Docker (Testcontainers): Accurate, but slow. Spinning up a container takes seconds; running parallel tests requires heavy resource management.
RustMemDB is the Third Way.
It is a pure Rust SQL engine with MVCC and Snapshot Isolation that introduces a paradigm shift in testing: Instant Database Forking.
⚔️ Comparison Matrix
| Feature | RustMemDB 🦀 | SQLite :floppy_disk: | Docker (Postgres) 🐳 |
|---|---|---|---|
| Startup Time | < 1ms | ~10ms | 1s - 5s |
| Test Isolation | Instant Fork (O(1)) | File Copy / Rollback | New Container / Truncate |
| Parallelism | ✅ Safe & Fast | ❌ Locking Issues | ⚠️ High RAM Usage |
| Type Safety | ✅ Strict | ❌ Loose / Dynamic | ✅ Strict |
| Dependencies | Zero (Pure Rust) | C Bindings | Docker Daemon |
🚀 Killer Feature: Instant Forking (COW)
Stop seeding your database for every test function.
RustMemDB uses Persistent Data Structures (Copy-On-Write) via the im crate to clone the entire database state instantly.
The "Seed Once, Test Anywhere" Workflow:
Step 1: Setup (Runs once)
[ Master DB ] <--- Create Tables, Insert 50k Seed Rows (Heavy)
|
+------------------------+------------------------+
| (Microseconds) | (Microseconds) |
▼ ▼ ▼
[ Fork: Test A ] [ Fork: Test B ] [ Fork: Test C ]
Delete ID=1 Update ID=2 Select Count(*)
(Isolated Change) (Isolated Change) (Sees Original Data)
Code Example
use Client;
async
📊 Benchmarks
Time taken to create an isolated database environment ready for a test:
RustMemDB (Forking): [=] < 1ms 🚀
SQLite (In-Memory): [==] 10ms
Docker (Postgres): [==================================================] 2500ms+
RustMemDB is approximately 2500x faster than spinning up a Docker container for isolation.
✅ SQL Support Matrix
We support a rich subset of SQL-92, focusing on the features most used in application logic.
| Category | Supported Features |
|---|---|
| Data Types | INTEGER (i64), FLOAT (f64), TEXT, BOOLEAN, NULL |
| Operators | +, -, *, /, % |
| Comparisons | =, !=, <, >, <=, >= |
| Logic | AND, OR, NOT, Parentheses ( ) |
| Predicates | LIKE (Pattern matching), BETWEEN, IS NULL, IS NOT NULL, IN (list) |
| Aggregates | COUNT(*), SUM(col), AVG(col), MIN(col), MAX(col) |
| Constraints | PRIMARY KEY (Unique + Not Null), UNIQUE |
| Statements | CREATE/DROP TABLE, CREATE INDEX, INSERT, UPDATE, DELETE, SELECT |
| Clauses | WHERE, ORDER BY (Multi-column), LIMIT |
| Transactions | BEGIN, COMMIT, ROLLBACK |
🧩 Extensibility & Plugins
RustMemDB is built for Rust developers. Expanding the database with custom functions is trivial compared to C-based databases (SQLite/Postgres).
Goal: Add a custom SCRAMBLE(text) function.
use ;
use ExpressionEvaluator;
;
// Register and use immediately
db.register_function;
let result = db.query; // Returns 'olleh'
👩💻 Developer Experience (DX)
We believe databases should be a joy to use, not a black box.
1. Pure Rust & Async-Native
No C compilers, no libsqlite3-dev dependencies, no FFI overhead. RustMemDB is async from the ground up, built on tokio.
2. Helpful Error Messages
Stop guessing why your query failed.
Error: TypeMismatch
=> Column 'age' expects INTEGER, got TEXT ('twenty')
3. Strict Type Safety
Unlike SQLite, RustMemDB enforces types. If you define an INTEGER column, you cannot insert a string. This catches bugs in your application logic before they hit production.
🎯 Ideal Use Cases
RustMemDB isn't trying to replace PostgreSQL in production. It excels where others fail:
1. High-Concurrency CI/CD
Run 1000s of integration tests in parallel without managing Docker containers or worrying about port conflicts.
- Benefit: Reduce CI times from minutes to seconds.
2. Rapid Prototyping
Drafting a schema or an API? Don't waste time setting up docker-compose.yml. Just cargo run and you have a SQL engine.
- Benefit: Zero-config development environment.
3. Embedded Logic Engine
Need to query internal application state using SQL? Use RustMemDB as an embedded library to store configuration or session data.
- Benefit: Query your app's memory with
SELECT * FROM sessions WHERE inactive > 1h.
🛡️ Safety & Reliability
Built on Rust's guarantees.
- Memory Safety: Zero
unsafeblocks in core logic. Immune to buffer overflows and use-after-free bugs that plague C-based databases. - Thread Safety: The compiler guarantees that our MVCC implementation is free of Data Races.
- Atomic Transactions: If a transaction isn't committed, it's rolled back. No partial writes, ever.
🔌 The "Drop-In" Architecture
RustMemDB provides a standardized DatabaseClient trait. Write your business logic once, and run it against RustMemDB in tests and Postgres in production.
Your Service:
use ;
Production (main.rs):
// Wrapper for tokio-postgres
let pg_client = connect.await?;
let service = new;
Testing (tests.rs):
// Works instantly!
let mem_client = connect_local.await?;
let service = new;
💾 Persistence & Durability
"In-memory" doesn't mean "data loss". RustMemDB supports full persistence via Write-Ahead Logging (WAL).
use ;
async
🧩 Extensibility & Plugins
RustMemDB is written in Rust, for Rust developers. It exposes a powerful Plugin API. Want to add a custom function? You don't need C-extensions.
// Define a custom evaluator
;
// Register it
db.register_function;
// Use it immediately
db.query;
⚙️ Engineering Internals
We take engineering seriously. This is not just a Vec<Row>.
- MVCC (Multi-Version Concurrency Control):
- Writers never block readers.
- Readers never block writers.
- Full Snapshot Isolation support.
- Persistent Data Structures:
- Uses
im-rsfor O(1) cloning and efficient memory usage. - Tables are structural-shared trees, not flat arrays.
- Uses
- Indexing:
- B-Tree backed indexes for
PRIMARY KEYandUNIQUEconstraints. - Lookup time is
O(log n), notO(n).
- B-Tree backed indexes for
- Lock-Free Catalog:
- Schema metadata is accessed via
ArcandCopy-On-Write, eliminating read contention on the catalog.
- Schema metadata is accessed via
❓ FAQ
Q: Can I use this in production? A: Use Postgres or MySQL for critical production data storage. Use RustMemDB for testing, prototyping, or embedded scenarios where Postgres is overkill.
Q: Is it faster than HashMap?
A: No. A HashMap is O(1). A SQL engine handles Parsing, Planning, and Transactions. Use RustMemDB when you need Relational Logic (Joins, Where clauses, transactions), not just Key-Value storage.
Q: Does it support the Postgres Wire Protocol? A: Not yet (Planned). Currently, you use it via the Rust library API.
📦 Installation
Add this to your Cargo.toml:
[]
= "0.1.1"
🤝 Contributing
We are building the best testing database for the Rust ecosystem.
- Found a bug? Open an issue.
- Want to build a feature? Check
docs/DEVELOPER_GUIDE.md.
📄 License
MIT. Use it freely in your OSS or commercial projects.
Built with ❤️ in Rust