The SQLite of document databases — two Rust servers, one embedded store.

SecantusDB is a real database server backed by the same WiredTiger engine MongoDB ships, written in Rust from the wire up. Run secantusd-rs and any MongoDB driver connects unchanged; run secantusd-pg and psql, psycopg and SQLAlchemy reach the same store over the PostgreSQL wire protocol. One process, no interpreter, no cluster to model.

Beta Past initial proving, but the Python API surface may still shift before 1.0. WiredTiger on-disk format is stable, but there's no migration tool yet — don't put production data here.

Two Rust servers, two wire protocols, one store

The MongoDB server and the PostgreSQL server are separate binaries with nothing shared at the wire, and the same WiredTiger storage underneath — a directory one writes, the other reads. Behind them both sits the pure-Python reference implementation they are held to.

Rust · MongoDB wire

Rust MongoDB server

The flagship. Wire, dispatch, cursors, change streams and WiredTiger storage, all in Rust — shipped as one static binary with nothing else to install.

  • One dependency-free executable: secantusd-rs
  • Prebuilt for Linux, macOS and Windows — no Python at all
  • Twelve unmodified driver suites score it, not us
  • Measured at 0.9×–2.4× of mongod per operation

Meet the Rust MongoDB server →

Rust · PostgreSQL wire

Rust PostgreSQL server

The same Rust storage answering the PostgreSQL wire protocol instead — real SQL, real transactions, over the same WiredTiger home a MongoDB client writes to.

  • psql, psycopg, SQLAlchemy, JDBC — stock clients
  • PostgreSQL's own parser, so the SQL is parsed the way PG parses it
  • Transactions, two-phase commit, COPY, LISTEN/NOTIFY, server cursors
  • 5,545 of psycopg 3's 5,729 own tests pass, unmodified — one failure

Meet the Rust PostgreSQL server →

Python · the reference

The Python servers

Where SecantusDB started, and still the specification the Rust servers are held to — every operator landed here first, and the Rust ports are pinned to it byte-for-byte.

  • Pure-Python request path — readable, hackable, patchable
  • pip install SecantusDB → a server in two lines
  • Reach for it to read or change the engine
  • Reach for Rust to run it

The reference implementation →

Drop-in for pymongo

Same wire protocol, same handshake, same error codes — against a real mongod or against secantusd-rs. The application code is byte-identical; only the setup line changes. The snippet on the right embeds the Python reference server, which is still the shortest way to get a server inside a test.

Normal MongoDB requires mongod running on :27017
from pymongo import MongoClient

client = MongoClient("mongodb://localhost:27017")
db = client["mydb"]
db["users"].insert_one({"_id": 1, "name": "Joe"})
assert db["users"].find_one({"_id": 1})["name"] == "Joe"
Embedded SecantusDB no external process — in your test or app
from pymongo import MongoClient
from secantus import SecantusDBServer

with SecantusDBServer(port=27017) as server:
    client = MongoClient(server.uri)
    db = client["mydb"]
    db["users"].insert_one({"_id": 1, "name": "Joe"})
    assert db["users"].find_one({"_id": 1})["name"] == "Joe"

With a console in the box

One command opens a local web UI over whatever server you already have running — SecantusDB or a real mongod. Browse collections, watch live throughput, read a query plan, tail a change stream, manage users, take a backup. It's loopback-only and token-gated, and every script and stylesheet ships inside the package.

The SecantusDB admin dashboard: uptime, connection and request tiles above four per-second operation sparklines.
Live server metrics, sampled once a second over a websocket.
The admin Query page running a find, with results below the form.
Run find, aggregate or any command
The admin change-stream tail showing live insert, update and delete events.
Tail a change stream live
The admin explain view showing a winning query plan stage by stage.
See which index a query really used

Where the Python servers fit

SecantusDB began as a pure-Python MongoDB server, and that implementation is still here — not as a legacy shim but as the specification. Every operator, stage and error message landed in Python first, and the Rust ports are pinned to it byte-for-byte by parity suites that fail the build when the two disagree. It is the one you read when you want to know what SecantusDB does; it is also still the shortest path to a server inside a test, at two lines and no external process. What it is not is fast — it runs 2–23x slower than mongod and loses throughput under concurrent writers, which is the gap the Rust servers exist to close.

Every major MongoDB driver works

SecantusDB is validated against the official driver test suites, unmodified — the same tests the driver maintainers run against a real mongod. Twelve driver gauges — Python (sync and async), Java, Node.js, Go, Ruby, Rust, PHP (library and C extension), C, C++, and C#/.NET. One wire protocol. pymongo is the headline gauge: it runs the broadest in-scope set, which makes it the most honest single number. The rest run curated, in-scope subsets in each driver's own language — their job is to catch wire-protocol bugs pymongo's permissive client accepts silently (cursor IDs that must be int64, strict type decoding), not to pile up a bigger count. Where a gauge sits below 100%, the shortfall is out-of-scope surface (text / hashed indexes, server-side $where JavaScript, multi-node assumptions) rather than a gap in the CRUD, aggregation, or change-stream behaviour that test and dev work depends on — each panel links its full report. The figures below are the Python reference server's runs; the Rust MongoDB server is put through the same unmodified suites and publishes its own per-driver reports alongside them.

pymongo

Python
99.5% pass rate

1021 tests passed · 5 known divergences

The official MongoDB Python driver, and the deepest suite we run — so it surfaces the long tail. The remaining failures are features outside a single node's scope (text / hashed indexes, server-side $where JavaScript), tests that assume a multi-node cluster, and a few driver-side harness artifacts — not gaps in the CRUD, aggregation, or change-stream surface that test and dev rely on. We run pymongo's own tests, unmodified, against an embedded SecantusDB.

Read the report →

pymongo (async)

Python / asyncio
99.4% pass rate

926 tests passed · 6 known divergences

pymongo's native AsyncMongoClient suite — the async/await wire path that replaced Motor. Same unmodified upstream tests as the sync gauge, run under pytest-asyncio against the same embedded SecantusDB, so the non-blocking client is held to the same bar rather than assumed to follow from the sync one. Remaining failures are the same out-of-scope surfaces (text / hashed indexes, server-side $where) plus a few timeout-introspection tests.

Read the report →

mongo-java-driver

Java
100.0% pass rate

447 tests passed · 0 failed

The driver enterprise MongoDB consumers most often use, and the foundation for many JVM-language wrappers. We run a curated subset of driver-sync/src/test/functional/ — integration tests that open a real connection to a SecantusDB daemon (the driver's own BSON codec unit tests are run but not counted here; they never touch the server). Type-strict decoders catch wire-shape divergences pymongo's permissive client accepts silently.

Read the report →

mongo-kotlin-driver

Kotlin
100.0% pass rate

294 tests passed · 0 failed

The official Kotlin driver, which ships inside the mongo-java-driver monorepo and is the coroutine-friendly entry point for JVM services written in Kotlin. We run its :driver-kotlin-sync:integrationTest suite unmodified against a standalone SecantusDB daemon, through the same two-phase auth setup the Java gauge uses.

Read the report →

mongo-node-driver

Node.js
99.7% pass rate

358 tests passed · 1 known divergence

The official Node driver, and the same driver mongosh and the JavaScript ecosystem build on. We run a curated test/integration/ spec set via mocha --config test/mocha_mongodb.js — real wire commands against an embedded SecantusDB daemon.

Read the report →

mongo-go-driver

Go
100.0% pass rate

401 tests passed · 0 failed

The same driver mongodump and mongorestore are built on. We run ./internal/integration/... — the package that opens real mongo.Client instances and exchanges wire commands. Type-strict (int32 vs int64) bugs that pymongo accepts silently fail loudly here.

Read the report →

mongo-ruby-driver

Ruby
99.6% pass rate

258 tests passed · 1 known divergence

The official MongoDB Ruby driver (mongo + bson 5.x), the gem the Rails / Sinatra ecosystem builds on. We run a curated set of integration spec files end-to-end against an embedded SecantusDB daemon — every test opens a real Mongo::Client, SCRAM-authenticates as a pre-provisioned root-user, and exchanges wire commands.

Read the report →

mongo-rust-driver

Rust
100.0% pass rate

101 tests passed · 0 failed

The official MongoDB Rust driver — the basis for Tokio-async MongoDB consumers in Rust. We run a curated set of driver/src/test/ in-tree tests via cargo test --lib -p mongodb with MONGODB_URI explicitly overridden in the subprocess env, so the rust driver's fallback chain ($MONGODB_URI~/.mongodb_urilocalhost:27017) can't accidentally route to a real mongod.

Read the report →

mongo-php-library

PHP
100.0% pass rate

2184 tests passed · 0 failed

The official high-level PHP library — the mongodb/mongodb package Laravel and Symfony applications build on. We run its PHPUnit functional suite (Operation / Collection / Database / Command) end-to-end against an embedded SecantusDB daemon; the pure-code query-builder and BSON-comparator units are run but not counted here, since they never touch the server.

Read the report →

mongo-php-driver

PHP
100.0% pass rate

247 tests passed · 0 failed

The low-level PHP extension — the C-based PECL ext-mongodb that wraps libmongoc and underpins the library above. We run its .phpt wire-protocol suite via PHP's run-tests.php against an embedded SecantusDB daemon (the pure BSON-serialization tests are run but not counted). Alongside Go, the strictest wire-shape check we run — type divergences pymongo accepts silently fail here.

Read the report →

mongo-c-driver

C
99.0% pass rate

760 tests passed · 2 failed

The official MongoDB C driver (libmongoc) — the lowest-level official client, the one the PHP, Ruby (bson), and PyMongo C-extensions ultimately wrap. We build its test-libmongoc suite from source and run a curated set of wire-protocol prefixes (CRUD / cursor / aggregate / command / GridFS / index management) against an embedded SecantusDB daemon via MONGOC_TEST_URI. A strict C client — type and wire-shape divergences surface here that permissive clients accept.

Read the report →

mongo-cxx-driver

C++
100.0% pass rate

890 tests passed · 0 failed

The official MongoDB C++ driver (mongocxx), built on libmongoc. We build its Catch2 test_driver suite from source and run it (CRUD / cursor / aggregate / GridFS / commands) against an embedded SecantusDB daemon. mongocxx's tests hard-wire the driver default port, so the gauge serves them on 127.0.0.1:27017.

Read the report →

mongo-csharp-driver

C#
100.0% pass rate

202 tests passed · 0 failed

The official MongoDB C# / .NET driver — the one the .NET / Unity / Xamarin ecosystem builds on. We run its xUnit CRUD specification suite (MongoDB.Driver.Tests.Specifications.crud) via dotnet test against an embedded SecantusDB daemon, with MONGODB_URI pointed at it. The driver's [RequireServer] attribute self-skips version- and topology-gated cases.

Read the report →

Plus a cross-driver feature matrix: every shipped feature (auth, change streams, custom roles, sessions, geo, bulk writes, type fidelity…) is verified end-to-end through the Python / Java / Node / Go / Ruby / PHP drivers via dedicated smoke tests — so a wire-shape divergence that one driver is permissive about gets caught by another.

A note on the license: SecantusDB is GPL-2.0-only. The GPL's obligations apply when you distribute SecantusDB or a derivative of it — not when you run it. Your application talks to it through a standard MongoDB driver over the wire protocol, and a test/dev dependency you don't ship leaves your application's license untouched.