[{"content":"Twenty years ago I was writing PHP 5 code that talked to MySQL 4.1 through mysql_*. The whole stack was a LAMP box, a single MySQL server, an .htaccess file, and a prayer. Back then \u0026ldquo;embedded database\u0026rdquo; basically meant SQLite or nothing, and SQLite was for client apps, not production server work.\nThings have changed. The embedded database category has real options now — SQLite (which grew up and got serious), DuckDB (analytical powerhouse), libSQL (SQLite\u0026rsquo;s networked fork), RocksDB and LMDB (KV primitives), and now MongrelDB. I want to talk about this last one because it does something genuinely different.\nWhat MongrelDB is MongrelDB is an embedded, single-node, log-structured columnar database written in Rust. The name is a deliberate riff on MongoDB — and the joke is the point. A mongrel is a mixed-breed dog, and MongrelDB takes the good parts from several places and bolts them together. Some of those bolts are welded; some are still held on with baling wire. We\u0026rsquo;ll get to which is which.\nThe headline numbers from the project\u0026rsquo;s own cross-engine benchmarks at 1M rows:\nSingle-row durable write: 7.7 µs — about 1.8× faster than SQLite (14.2 µs), 37× faster than DuckDB (301 µs) Single-row durable update: 7.4 µs Bulk insert: 2.3× SQLite, 2.6× DuckDB native COUNT(*) is O(1) by design — 0 µs Storage: 4.17 bytes/row at 1M rows Take vendor benchmarks with the usual grain of salt, but these aren\u0026rsquo;t outlandish. The architecture backs them up.\nHow it\u0026rsquo;s built (and why it matters) Write path: a WAL feeds a Bε-tree memtable, which flushes to immutable sorted runs in a custom .sr PAX columnar format. Read path: merge memtable + sorted runs under MVCC snapshot isolation. This is LSM with some twists.\nThe unusual part is the eight index kinds in a shared RowId space:\nHOT — trie for primary-key point lookup Bitmap — Roaring for low-cardinality equality PGM — learned range index (shrinking-cone, ε-bounded) FM-index — BWT + wavelet tree for substring / FTS HNSW — approximate nearest neighbor for vectors PMA — cache-oblivious sorted runs Sparse — inverted token lists for learned-sparse retrieval MinHash — LSH for set similarity (dedup / join) You compose conditions in RowId space, then decode only the matching rows and the columns you asked for. That hybrid model — bitmap equality intersected with HNSW ANN intersected with FM substring — is what modern AI retrieval actually needs. Most embedded engines give you a B-tree and a hash index and call it done.\nPredicate and projection pushdown go all the way to the page level. Each 65,536-row page carries populated min/max; the reader skips whole pages whose range excludes your predicate. Encrypted columns keep their min/max in a per-run AES-256-GCM stats envelope, so they prune identically to plaintext. The 1.87 GiB/s AES throughput is hardware-accelerated and adds under 5% to typical workloads.\nThe SQL frontend is DataFusion 54, which means recursive CTEs, window functions, CREATE TABLE AS SELECT, materialized views, multi-statement execution, and a mongreldb_fts_rank UDF for FTS ranking. You can embed the engine in-process (the better-sqlite3 model) or run an optional mongreldb-server daemon (axum/tokio) for multi-process access.\nAround the engine you get real database features: WAL-streamed replication (read-scaling, not write-scaling), change data capture via NOTIFY/LISTEN + SSE, Argon2id user/role/GRANT, page-level AES-256-GCM encryption with a proper key hierarchy, and per-table unique / FK / CHECK constraints enforced in the core transaction path — not in your app code.\nLanguage bindings are real, not vapor: Rust core, Node NAPI addon, pure-PHP 8.4+ (no C extension, talks HTTP to the daemon), Python and TypeScript via MongrelDB Kit (schema-aware query builder, migrations, multi-language parity, content-addressed migration checksums).\nWhere it fits in 2026 The embedded database market has roughly four niches:\nOLTP embedded — SQLite, libSQL. Single-row writes, simple reads, durable, tiny footprint. SQLite is the 800-pound gorilla. OLAP embedded — DuckDB. Bulk reads, analytical queries, columnar. Wins on filter and aggregation throughput. KV embedded — RocksDB, LevelDB, LMDB. Lower-level primitives; you build indexes on top. AI-native storage — Qdrant, Lance, SQLite extensions. Optimized for vector search and learned indexes. MongrelDB is trying to sit across (1) and (4) with some of (2)\u0026rsquo;s analytical chops. The pitch is: \u0026ldquo;Your app\u0026rsquo;s primary storage AND your vector search AND your FTS AND your learned-sparse retrieval, in one embedded engine, with no separate vector DB to sync.\u0026rdquo;\nThat\u0026rsquo;s a real pitch. The eight-index approach is what makes it more than marketing.\nThe Pros Writes are genuinely fast. Sub-10µs single-row durable writes in an embedded engine is a real achievement. SQLite is fast; this is faster. DuckDB isn\u0026rsquo;t in the same race for OLTP. AI-native is not marketing. HNSW, Sparse, and FM-index are first-class indexes, not query-time hacks. The hybrid query model matches what AI retrieval actually needs. Encryption is built in, not bolted on. Page-level AES-256-GCM with a real key hierarchy (passphrase → Argon2id → KEK → DEK, or raw key file), HMAC\u0026rsquo;d run metadata, and pruning preserved on encrypted columns. Constraints in the core. Unique, FK, and CHECK are enforced at the storage layer. Same for auth — require_auth makes the engine itself reject unauthenticated opens, not just the daemon front-door. The Rust + DataFusion choice is smart. Rust for memory safety and FFI ergonomics, DataFusion for the SQL parser/optimizer/planner. Years of battle-tested code you\u0026rsquo;re not re-implementing. MongrelDB Kit is the right abstraction. Cross-language schema, migrations, query builder, triggers, async variants, type generation. That\u0026rsquo;s how you build a real ecosystem, not just a core and \u0026ldquo;good luck.\u0026rdquo; The name is honest. A mongrel is a mixed-breed dog. MongrelDB is a mixed-architecture database. They named it for what it is, and that earns points in a category full of overpromising. The Cons (honest tradeoffs) It\u0026rsquo;s new. SQLite has been hammered on for 25 years in production. MongrelDB is new enough that you don\u0026rsquo;t have a community of people who have hit the edge cases for you. Auth, replication, and CDC are real, but they\u0026rsquo;re version 1.0 of those features. Expect rough edges. No network mode by default. Like SQLite, you embed it in-process. The daemon exists for multi-process access, but it\u0026rsquo;s not what MongoDB/PostgreSQL users expect. If you need horizontal scale, this isn\u0026rsquo;t it — single-node, period. Replication is read-scaling (followers), not write-scaling. No KMS integration. Page-level encryption is solid, but there\u0026rsquo;s no AWS KMS, GCP Cloud KMS, Azure Key Vault, or HashiCorp Vault. You bring your own key (passphrase or key file) and you manage it. For regulated workloads, that\u0026rsquo;s a checklist item you handle yourself. DataFusion is a moving target. Pinning to \u0026ldquo;DataFusion 54\u0026rdquo; is great for now. It also means the SQL surface depends on what DataFusion ships. If you want a feature DataFusion doesn\u0026rsquo;t have, you\u0026rsquo;re at the mercy of upstream. Eight indexes is also a footgun. Having every kind of index doesn\u0026rsquo;t mean you should build all eight on a single table. The planner has to make smart choices; bloat the index set and writes pay the cost. PHP needs a daemon. The PHP client is pure-PHP with no C extension, but it talks to mongreldb-server over HTTP. If you wanted in-process PHP (like PDO/SQLite), you won\u0026rsquo;t find it here. The NAPI addon is the in-process model; PHP doesn\u0026rsquo;t get that path. The benchmark comparisons are self-published. Cross-engine benchmarks on the vendor\u0026rsquo;s own machine, with the vendor\u0026rsquo;s own workloads. Real production data will be different. Run your own before you commit. Who should use it MongrelDB is interesting if you\u0026rsquo;re:\nBuilding a Node.js, TypeScript, Python, or PHP app that needs a single embedded store and doesn\u0026rsquo;t want to run a separate server. Building an AI-native app where vector search, FTS, and learned-sparse retrieval are first-class features of the primary store, not bolt-ons synced from somewhere else. Comfortable being on a newer engine, trading some ecosystem maturity for a tighter architectural fit. Running a service-oriented architecture where each service can have its own database and you don\u0026rsquo;t need cross-service joins at the storage layer. Who should probably wait You need a managed, hosted, multi-region replicated database. This isn\u0026rsquo;t that. Your application is plain CRUD on a normalized schema and SQLite is already serving you fine. SQLite is the safer default. You\u0026rsquo;re doing heavy analytical workloads over millions of rows. DuckDB is still the king there, and exporting to DuckDB via Parquet is a well-trodden path. You need deep compliance certifications (SOC2, FedRAMP, HIPAA-eligible). New engines take time to get there. You need a 24/7 community on Stack Overflow. SQLite\u0026rsquo;s tag has 100k+ questions. MongrelDB\u0026rsquo;s has, well, fewer. The verdict MongrelDB is a serious attempt at a thing that hasn\u0026rsquo;t really existed: a single embedded engine that handles both OLTP and AI-native retrieval, with real SQL, real encryption, real auth, and a real cross-language ecosystem. It\u0026rsquo;s not a MongoDB killer (different category) and it\u0026rsquo;s not a SQLite killer (different priorities). It\u0026rsquo;s its own thing.\nThe name is honest. A mongrel is what you get when you breed the parts that work and ignore the breed standard. MongrelDB is log-structured columnar storage with MVCC, a learned-index flavor, real encryption, and a DataFusion SQL frontend — all in an embedded Rust engine. The mongrel analogy holds.\nIf you\u0026rsquo;re building a Node.js or Python AI app and you don\u0026rsquo;t want to stand up Qdrant + Postgres + a sync layer, look at this. If you\u0026rsquo;re writing PHP 8.4 and you\u0026rsquo;re tired of the SQLite-or-MySQL choice, this is worth a serious look. If you\u0026rsquo;re running SQLite in production and everything works, you have no urgent reason to migrate — but you should know what\u0026rsquo;s coming.\nThe bar for \u0026ldquo;yet another database\u0026rdquo; is high, and a lot of \u0026ldquo;yet another databases\u0026rdquo; fail. MongrelDB has the architecture and the benchmarks to make a case. Now it needs production years. If you\u0026rsquo;re willing to be one of the early ones, this is one of the more interesting bets in the embedded space right now.\n","permalink":"https://www.mongreldb.com/articles/2026/07/mongreldb-what-it-is-what-it-isnt-and-where-it-fits/","summary":"\u003cp\u003eTwenty years ago I was writing PHP 5 code that talked to MySQL 4.1 through \u003ccode\u003emysql_*\u003c/code\u003e. The whole stack was a LAMP box, a single MySQL server, an \u003ccode\u003e.htaccess\u003c/code\u003e file, and a prayer. Back then \u0026ldquo;embedded database\u0026rdquo; basically meant SQLite or nothing, and SQLite was for client apps, not production server work.\u003c/p\u003e\n\u003cp\u003eThings have changed. The embedded database category has real options now — SQLite (which grew up and got serious), DuckDB (analytical powerhouse), libSQL (SQLite\u0026rsquo;s networked fork), RocksDB and LMDB (KV primitives), and now MongrelDB. I want to talk about this last one because it does something genuinely different.\u003c/p\u003e","title":"MongrelDB: What It Is, What It Isn't, and Where It Fits"}]