Beta v0.5.1b24 — 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.
SecantusDB — the SQLite of document databases

Embeddable Document Database compatible with MongoDB.

SecantusDB is a real MongoDB server written in Python: it speaks the MongoDB wire protocol on the same TCP socket a mongod would, so any standard driver — pymongo, mongo-go-driver, mongosh, mongodump — connects unchanged. Backed by the same WiredTiger engine MongoDB uses.

Why SecantusDB

Build for full production use (eventually) right now use it as a cheap and easy clone for test and dev environments. Each panel links to the reference docs.

Drop-in wire protocol

Speaks MongoDB OP_MSG / OP_QUERY on a real TCP socket. pymongo, the Go driver, mongosh, and mongodump all connect with no code changes.

Architecture →

Single-node by design

No replica sets, no sharding, no cluster topology to model. Within single-node scope SecantusDB is a faithful surrogate — same handshake, same error codes.

Compatibility →

Python-native & embeddable

Start a server in two lines from any test or app. No mongod to install, no port juggling, parallel-test friendly. Or run it as a standalone daemon (secantusdb).

Quickstart →

Real WiredTiger storage

The same C library MongoDB ships with, vendored and built into the wheel. B-trees, page eviction, write-ahead logging, durability — all real.

Storage architecture →

Aggregation pipeline

Full pipeline — $match, $group (every mongod accumulator), $lookup with index-driven joins, $facet, $bucket, $densify, $fill, $merge, $out, $graphLookup, $geoNear. Same expression language as mongod.

Aggregation reference →

Geospatial — 2d & 2dsphere

$geoWithin, $geoIntersects, $near, $nearSphere, $geoNear all accelerated by either index type. S2 cell coverings for GeoJSON; quadtree-decomposed Z-order ranges for legacy [x, y] pairs. Compound geo+scalar indexes work too.

Geospatial reference →

Native TLS & mTLS

Wraps accepted sockets in TLS before the wire protocol starts — no reverse proxy required. Add a CA bundle for mTLS (transport-layer client-cert verification). SCRAM-SHA-256 still identifies the user on top.

Configure TLS →

Change streams

Oplog-backed, single-node. watch() at collection / db / cluster scope, resume tokens, fullDocument: "updateLookup", pre-images via changeStreamPreAndPostImages, awaitData blocking.

Change-streams reference →

Conformance-tested

Validated against the unmodified pymongo, mongo-go-driver, mongo-node-driver, mongo-ruby-driver, and mongo-java-driver test suites. The pass rates are the honest compatibility gauge.

Validation summary →

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. Five drivers, five ecosystems, one wire protocol.

pymongo

Python
100.0% pass rate

1039 tests passed · 0 failed

The official MongoDB Python driver. The pymongo conformance suite is the primary gauge for SecantusDB — we run pymongo's own tests, unmodified, against an embedded SecantusDB.

Read the report →

mongo-java-driver

Java
100.0% pass rate

4256 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/ plus the BSON unit tests against an embedded SecantusDB daemon. Type-strict decoders catch wire-shape divergences pymongo's permissive client accepts silently.

Read the report →

mongo-node-driver

Node.js
100.0% pass rate

358 tests passed · 0 failed · 1 documented failure (see report)

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
100.0% pass rate

293 tests passed · 0 failed · 1 documented failure (see report)

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 Feature smokes
6 / 6 features verified

The official high-level PHP library, built on the C-based ext-mongodb extension. Same six features as the Ruby driver — type fidelity, RBAC, bulkWrite, listDatabases filter, logical sessions, cluster-role bundles — verified end-to-end via composer install + php <feature>_smoke.php.

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.

Drop-in for pymongo

Same wire protocol, same handshake, same error codes. The application code is byte-identical — only the setup line changes.

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"