Open source embedded database

MongrelDB

A local database for writes, scans, search, vectors, ranges, and encrypted storage.

MongrelDB is an open source embedded database for applications that need more than key-value lookup, but do not want to operate a separate service for every access pattern. Store data locally, query it with SQL or native APIs, and combine equality, range, text, vector, and sparse retrieval in one engine.

6secondary index kinds around a shared RowId core
4.48µsaccepted single-row put (no fsync); durable fsync commit 4.67 ms
O(1)metadata-backed count path for known cardinalities
Localembedded storage in a self-contained directory, with optional encryption
Overview

One embedded engine. Fewer moving parts.

Embedded databases are strongest when they stay close to the application. MongrelDB keeps that deployment model while adding the access paths modern software often has to bolt on later. It is an independent engine, not a MongoDB fork or MongoDB-compatible replacement.

Hybrid indexing

Bitmap, PGM, FM, HNSW, Sparse/SPLADE, and MinHash secondary indexes, plus a dedicated primary-key path, all resolve through the same RowId space, making mixed predicates practical inside one engine.

Write-friendly columnar storage

Fast scans should not require giving up direct writes. MongrelDB uses a WAL and memtable in front of immutable PAX-columnar .sr runs.

Practical encrypted queries

ENCRYPTED_INDEXABLE columns use equality and range tokens to narrow candidate rows before plaintext is required.

Application-ready interfaces

Use SQL through DataFusion, Arrow IPC for batches, and NAPI bindings for Node. Keep local data local until your application needs to move it.

Multi-table ACID transactions

Cross-table commits stage on the shared WAL. Choose ReadCommitted, RepeatableRead, or Serializable (SSI-style certification), with savepoints and durable idempotent commits.

Scored hybrid retrieval

Beyond boolean intersection: named retrievers fuse with reciprocal-rank fusion, with optional exact-vector rerank and scored SQL table functions like hybrid_search_scored.

Indexes

Different access paths. One row identity.

Each index returns RowIds, so the engine can combine filters without forcing every workload through a single data structure.

Primary key

HOT primary-key point lookup

The HOT module resolves primary keys directly into the shared RowId space. The height-optimized trie it is named for is a planned drop-in; today's build runs a correct ordered-map back end behind the same surface.

  • Purpose-built for primary-key lookup and exact targeting.
  • Feeds the same RowId set used by the rest of the engine.
  • Fits OLTP-style read and update paths.
Equality

Roaring bitmap equality

Low-cardinality values compress into Roaring bitmaps, turning equality filters into set operations instead of table walks.

  • Useful for tenant, status, type, flag, and other low-cardinality columns.
  • Turns equality filters into set operations.
  • Combines cleanly with vector, substring, range, and sparse constraints.
Range

PGM range index

A shrinking-cone, epsilon-bounded learned model predicts where range keys live, then resolves qualifying rows into RowIds.

  • Designed for date, numeric, and ordered key ranges.
  • Small model footprint with bounded lookup correction.
  • Combines with dense-vector, sparse, equality, and substring filters.
Substring

FM-index containment

BWT plus wavelet-tree substring search lets containment queries use an index instead of falling back to a full scan.

  • Handles substring containment without adding a separate search service.
  • Converts text hits into RowIds for hybrid set math.
  • Complements SPLADE-style sparse retrieval and HNSW vector search.
Dense vectors

HNSW approximate nearest neighbor

Semantic similarity search lives beside text, equality, and range filters instead of requiring a separate vector database.

  • ANN candidate sets resolve to RowIds like every other access path.
  • Dense f32 cosine HNSW, with DiskANN, IVF, and product-quantization backends behind a swappable interface.
  • Intersect ANN with substring, bitmap, range, and sparse filters.
Sparse text

SPLADE-style sparse top-k

SPLADE-style sparse top-k retrieval with pluggable tokenization brings inverted-token scoring into the same engine as dense vectors, substring search, and ordinary filters.

  • Inverted token lists score top-k by sparse dot product.
  • Model-agnostic: bring your own tokenizer or learned sparse weights.
  • Works with dense-vector and substring retrieval instead of replacing them.
  • Designed for retrieval-heavy embedded applications.
Set similarity

MinHash LSH

MinHash supports approximate set similarity for deduplication and join-style retrieval, then returns RowIds like the other access paths.

  • Useful for near-duplicate detection and set joins.
  • Works as an LSH filter before exact checks.
  • Keeps set-similarity candidates inside the same RowId model.
Query model

Combine constraints before rows are decoded.

A vector match, substring filter, tenant predicate, and time range can all be represented as candidate RowId sets. MongrelDB intersects those sets first, then decodes the rows that remain.

HNSWvector ANN
FMsubstring
Bitmapequality
PGMrange
Shared RowIdcandidate intersection
ann_search(embedding, q, 50) fm_contains(body, "needle") tenant = "acme" created_at BETWEEN a AND b

When ranking matters more than set membership, named scored retrievers — ANN, sparse, and MinHash — fuse with deterministic reciprocal-rank fusion, and an optional stage reranks a bounded candidate window against exact stored vectors. The same machinery backs table.search in the Node addon and scored SQL table functions such as ann_search_scored and hybrid_search_scored.

Storage

Durable writes. Efficient scans.

The write path is log-structured. The read path resolves predicates to shared RowIds, decodes only the columns needed for the result, and keeps frequently requested answers close by.

01

WAL group commit

Durability starts with an append-only write-ahead log that can batch fsync work.

02

Bε-tree memtable

A composite-key (RowId, Epoch) MVCC Bε-tree memtable buffers updates in bulk before a packed-memory-array mutable-run tier coalesces small flushes into immutable runs.

03

PAX columnar .sr runs

Sorted-run pages support scans, compression, and projection pushdown in the embedded storage layer.

04

Hybrid pushdown

Equality, range, substring, vector, and sparse matches can be intersected before row decoding.

05

Arrow + DataFusion

SQL, Arrow IPC, and Node-native bindings provide familiar ways to work with local data.

06

Time travel & recovery

Query AS OF EPOCH snapshots, set retention and TTL policies, and restore from backups with point-in-time recovery.

Columnar scans without giving up single-row writes.

MongrelDB keeps durable writes in front of compressed runs, so applications can support updates and analytical reads in the same local store. A durable single-row update on a flushed table measures 4.28 ms.

Accepted put (no fsync)4.48µs
Durable commit (fsync)4.67 ms
Typed bulk load17.1 Melem/s

Fast reads without another service.

Memory-mapped runs, adaptive encodings, projection pushdown, page pruning, and a warm result cache keep read paths inside the embedded engine.

Bitmap equality, 1M rows124 Melem/s
Integer range, 1M rows113 Melem/s
Warm point query p501.04µs

Single-machine engineering measurements from BENCHMARKS.md in the repository, not cross-machine guarantees. Durable means fsync; accepted writes acknowledge before it.

Encryption

Encrypted storage with practical query support.

MongrelDB is designed to protect stored pages, authenticate metadata, and still let trusted predicates narrow work without decrypting the entire dataset first.

Decorative background image

Authenticated pages. Searchable tokens. Explicit tradeoffs.

Page-level AES-256-GCM protects sorted-run payloads, WAL segments, result cache entries, and index checkpoints. Run metadata is authenticated so tampering can be detected on open.

AES-256-GCMArgon2idHKDFHMAC tokensOPE ranges
Search while encrypted

Encrypted-indexable columns expose query tokens so equality and range predicates can resolve candidate rows without requiring a full decrypt-first scan.

Tamper-evident runs

Run metadata is authenticated, while encrypted page payloads are individually protected with AES-GCM tags.

Key hierarchy
  • Passphrase plus salt derives a table-level KEK through Argon2id and HKDF.
  • Per-run DEKs protect page payloads.
  • Separate domains protect WAL, result cache, index checkpoints, metadata MACs, and per-column tokens.
Compression choices

Delta, Dictionary, Zstd, and passthrough encodings can be selected per column, while memory-mapped runs and a metadata count path keep the embedded profile lean.

Access control with the daemon

The optional server adds users and roles with GRANT/REVOKE SQL, OIDC/JWKS sign-in, HashiCorp Vault Transit as an external key-management service, TLS 1.3 with optional mutual TLS, and a bounded audit log.

Developer API

Embedded deployment. Modern interfaces.

Use SQL when it is enough, native calls when query shape matters, and Arrow when columnar data needs to move efficiently.

Use it when a local database is the simpler architecture.

MongrelDB fits local-first apps, edge jobs, desktop tools, test harnesses, agent workflows, and Node services that benefit from embedded storage without a database server to operate.

Local storeDataFusion SQLNAPI addonAsync APIBigInt RowIdsArrow IPC
// Open one local database. Combine multiple access paths.
const { Database, ConditionKind } = require("@visorcraft/mongreldb");

const db = Database.open("./app-data");
const docs = db.table("docs");

const hits = docs.search({
  must: [
    { kind: ConditionKind.FmContains, columnId: 2, text: "needle" },
    { kind: ConditionKind.BitmapEq,   columnId: 3, text: "acme" },
    { kind: ConditionKind.RangeInt,   columnId: 4, int64Lo: fromTs, int64Hi: toTs },
  ],
  retrievers: [
    { kind: "ann", columnId: 5, name: "semantic", weight: 1, k: 50, embedding: query },
  ],
  limit: 20,
});

console.log(hits.length);
Beyond embedded

An optional server side, for when one process is not enough.

Embedded is the default, not the ceiling. The same engine ships behind an optional daemon with a TLS 1.3 native gRPC listener (OIDC or SCRAM sign-in), a MySQL wire-compatible TLS listener with an online migration tool, and async WAL replication into Raft-replicated HA or a tablet-sharded cluster — the cluster paths are exercised under deterministic simulation and fault injection.

Native gRPC + TLS 1.3OIDC & SCRAMMySQL wire listenerOnline MySQL migrationAsync WAL replicationRaft-replicated HATablet shardingDeterministic sim + fault injection

Stated plainly: distributed serializable transactions cover the landed path, and published failover timings are single-machine test-harness measurements, not deployment promises.

Tools

Work with MongrelDB your way.

MongrelDB stays open source whichever tool you choose. Start with the focused, free Viewer, or use Mongrel when your database work extends into other engines and infrastructure.

Free & open source

MongrelDB Viewer

Open a local MongrelDB folder or connect to mongreldb-server. Browse schemas and rows, run SQL, inspect indexes, and handle REINDEX and ANN maintenance in a focused desktop app for Linux, macOS, and Windows.

Schema & rowsSQL workbenchIndex inspectionMaintenanceMIT or Apache-2.0
Commercial workbench

Mongrel by VisorCraft

Use Mongrel when MongrelDB is one part of a broader workflow. Manage it alongside 30+ database engines, terminal and remote-file connections, Docker, Podman, Kubernetes, and API clients from one desktop workspace.

30+ databasesTerminals & filesDocker & PodmanKubernetesAPI clients
MongrelDB mark

Build with MongrelDB.

Explore the code, run the benchmarks, and try it against a workload that needs local writes, hybrid search, and analytical scans in one embedded database.