NEDB is an embedded, tamper-evident database built on a BLAKE2b hash chain and a content-addressed Merkle DAG. Every write is a new immutable version. Every row can carry a causal edge naming the writes that caused it. Any auditor can prove the history was never altered — offline, without trusting the server.
A relational database answers what is the value now? NEDB answers four questions natively — not with triggers and side tables, but with queryable, indexed, hash-chained primitives.
Current state, stored as content-addressed objects, BLAKE2b-verified on every read.
every documentEvery version is kept forever. Time travel to any past sequence — no vacuum, no archival tier, no garbage collection.
AS OF <seq>Bi-temporal valid time: what the world believed on a date, independent of when the row was written.
VALID AS OF "<date>"Causal provenance: every write can cite the writes that caused it. Trace the chain forward or backward.
TRACE caused_by [REVERSE]from nedb import NEDB db = NEDB("./mydata") # Time travel — the value at any past sequence, forever snap = db.seq db.put("users", "alice", {"age": 32}) db.get("users", "alice", as_of=snap) # → the prior version # Causal provenance — an edge in a hash-chained DAG, not a comment field db.put("inputs", "msg_1", {"text": "user prefers dark mode"}) seq_msg = db.seq db.put("beliefs", "dark_mode", {"value": True}, caused_by=[seq_msg], evidence="user_message", confidence=0.95) db.query('FROM beliefs WHERE _id = "dark_mode" TRACE caused_by') # → msg_1 db.query('FROM inputs WHERE _id = "msg_1" TRACE caused_by REVERSE') # → dark_mode # Tamper evidence — verifiable by anyone, offline assert db.verify()
Most systems log events. NEDB chains them. Each write's hash commits to the write before it, the running Merkle head commits to everything, and the state root commits to the present — three separate commitments with different jobs.
One flipped byte anywhere in the object store and verify() returns false. Writes are atomic; reads re-verify hashes. There is no mode where the chain is quietly skipped.
caused_by is an indexed DAG edge. TRACE walks it in both directions at query speed, and metadata columns (_hash, _seq, _caused_by) select like any other column.
Merkle proofs verify locally with verify_proof() — a client can check a row existed at a time without database access. State roots compare two replicas in one hash.
Judged on the four axes plus the operational basics. NEDB is a single-node embedded/daemon database — it does not pretend to be a distributed cluster; the comparison is about what a database can be asked and prove.
| NEDB | SQLite | Redis | MongoDB | PostgreSQL | Dolt | |
|---|---|---|---|---|---|---|
| Time-travel reads | ✓ any seq, forever | ✗ | ✗ | ✗ | MVCC, until vacuum | ✓ commit-based |
| Bi-temporal (valid time) | ✓ native clause | ✗ | ✗ | ✗ | ✗ needs extension | ✗ |
| Causal provenance (why) | ✓ graph edges + TRACE | ✗ | ✗ | ✗ | ✗ | ✗ |
| Hash-chain tamper evidence | ✓ per write | ✗ | ✗ | ✗ | ✗ | Merkle-ish via commits |
| Third-party verifiable proofs | ✓ Merkle proofs | ✗ | ✗ | ✗ | ✗ | commit hashes |
| Encrypted at rest, built-in | ✓ AES-256-GCM | via extension | ✗ | paid tiers | via extension | ✗ |
| SQL surface | ✓ PostgreSQL grammar (neSQL) | ✓ | ✗ | own query lang | ✓ the standard | ✓ MySQL dialect |
| Wire protocols | HTTP · RESP2 · PostgreSQL | in-process only | ✓ RESP2 | ✓ own | ✓ libpq | ✓ MySQL |
| Embedded (no server) | ✓ Python/Node/Rust | ✓ | ✗ | ✗ | ✗ | ✗ |
| Idempotent, replay-protected writes | ✓ | ✗ | SETNX-class | ✗ | ✗ | ✗ |
| Git-style branch / merge of data | via nesql CLI (tag/branch/merge) | ✗ | ✗ | ✗ | ✗ | ✓ the whole point |
SQLite row is the stock engine; extensions (sqlean, SEE) can add pieces. Redis ≥6 has TLS in transit but no native at-rest encryption. MongoDB encrypted storage engine requires Enterprise Advanced. PostgreSQL row reflects core + common extensions (temporal_tables). Every cell is stated to the best of our knowledge as of Sept 2026 — corrections welcome, we apply them publicly.
Audit-shaped workloads: agent memory (every belief cites its evidence), blockchain state (itcd runs its chainstate on NEDB), compliance trails, financial ledgers, RAG pipelines where a fact must be traceable to its source, and anything a regulator or a counterparty may one day ask you to prove.
Massively concurrent distributed writes (Postgres/CockroachDB territory), sub-microsecond cache reads (Redis), or multi-TB analytical scans (column stores). NEDB is honest about its lane: proof-permitted, permanent-history storage for systems that think.
Every number below is dated, names its machine, and ships with the command that reproduces it. Absolute figures aren't cross-machine comparable — read the ratios. Time travel costs ~30%, not 10×.
| Operation | Throughput | Latency |
|---|---|---|
| PUT (durable, hash-chained) | 63.5K/s | 15.7 µs |
| GET (current state) | 1.33M/s | 0.75 µs |
| GET (AS OF — time travel) | 942.9K/s | 1.06 µs |
| Query, eq index | 1.45M/s | 0.69 µs |
| Query, full-text SEARCH | 492.3K/s | 2.03 µs |
| Operation | Throughput | p99 |
|---|---|---|
| Sequential writes | 418 ops/s | 3.3 ms |
| Point reads | 478 ops/s | 3.0 ms |
| Batch writes (500/req) | 1,104 ops/s | 1.2 ms |
| Hash join vs nested loop | 90.6× faster on equality joins | |
| Indexed point lookup (20k rows) | 137 ms → 0.01 ms (17,000×) | |
| Flush (coins → disk) | v2 loose store | v3 segment store |
|---|---|---|
| 2,002 coins / 275 kB | minutes | 1.93 s |
| 2,549 coins / 366 kB | minutes | 1.71 s |
NEDB is one Rust core with five ways in. No bespoke protocol lock-in — the PostgreSQL grammar is vendored wholesale (19,513 lines, 492 keywords, from PostgreSQL 17.4) and extended with the clauses only a permanent store can answer.
psql, psycopg3, asyncpg, JDBC, Metabase, DBeaver — both simple and extended protocols. A SQL UPDATE is a new version, a DELETE is a tombstone, and AS OF SYSTEM TIME works right in your existing SQL.
RESP2 wire protocol answers redis-cli directly, and wrap_redis() shadows an existing Redis app's writes into NEDB with one flag — the audit trail grows behind a running system.
Embedded Python and Node cores, a Rust crate, HTTP/JSON, and the nesql CLI that opens a store directly — no daemon, no port, machine-readable exit codes.
shop=> UPDATE orders SET total = 999 WHERE _id = 'o1'; shop=> SELECT total FROM orders WHERE _id = 'o1'; -- 999 shop=> SELECT total FROM orders AS OF SYSTEM TIME 0 WHERE _id = 'o1'; -- 120 — the old value, forever
NEDB was designed in production for AI agent memory — where "the model said so" is not an audit trail. It ships with the machinery to keep one honest.
A 3.33M-parameter local model turns prompts into queries on CPU, with the engine checking every plan against the live schema — invented collections get a 422 with the reason, never silent zero rows. Drift detection flags hallucinated literals. execute defaults to false.
NEDB's own model was trained with datasets → runs → checkpoints → evals all chained by caused_by. Any score traces to the exact data that produced it. The same primitive is yours for any pipeline.
tip(), a bounded since() changefeed, and a scan_status() readiness gate — plus state roots to prove two stores agree. SSE streams every write and its new Merkle head, live.
An evaluator's first job is finding out what a product won't claim. Here is ours, in writing.
TRUNCATE, NEDB refuses it on purpose.Every entry below is a real tag in this repository's history — git tag is the audit. Same hash-chain API across all of it: stores migrate forward automatically, client code never rewrote.
First commit ships the reference Python engine, the Rust core, and the tri-registry publish pipeline — together, on purpose.
v0.9.0: Causal Write Provenance — the commit calls it "the first embedded database with sealed causal chains." v1.0.0, same day: bi-temporal VALID AS OF. Day 3 of the project.
Shadowing, backfill, isolation guarantee. The adapter family starts here.
Content-addressed Merkle DAG replaces the AOF; --dag wired end-to-end within a day of the first alpha. Fourteen point releases in 24 hours.
Append-only packs, one fsync per batch, macOS fast-fsync. June 27: all three distributions aligned at one version on one tag — the pattern every release since has kept.
Flush-on-exit, nedb-cli, the inspector, and the replication contract (tip / since / scan_status).
nedb.client.NedbClient — the HTTP surface gets a first-class client with CAS transactions and Merkle proofs.
A 3.33M-parameter model trained inside the engine's own parser, shipped in the engine. Drift detection follows in v2.8.2.
Three defect classes found by killing a real engine at every persistence boundary — failed flushes, unobservable errors, a repair that couldn't repair.
The MIT era closes, the wrap family lands in all three languages, embedded bindings learn to flush on a cadence. v3.0.0–3.3.1 stay MIT forever.
Full boolean predicates in both engines, nine silent defects fixed, parity gated — then the relicensing: free under $1M revenue, Apache 2.0 at the Change Date.
Subqueries, set operations, LATERAL, the full psql \d matrix driven by the real binary — and the qualified-WHERE silent-zero-rows bug found and killed.
Cross-engine state-root vectors pinned; NQL's verbs folded into the SQL evaluator; the published grammar rewritten to match the product. neSQL reaches master.
One router for the daemon and the CLI — two front-ends can no longer disagree about what a statement means.
PostgreSQL's grammar + NEDB's clauses, the CLI that can actually publish, and the README rebuilt around provenance. Today.