Robot memories,
with a heartbeat
The embedded multimodal database for embodied AI & robotics
MoteDB is an embedded database that carries vectors · time series · text · binary in one SQL engine — from capture to fleet distribution, zero-ops, ready on open.
cargo add motedbpip install motedb-pythonnpm install motedb
MoteDB in 60 seconds
One SQL engine, four modalities — and the real numbers it produces.
- 1.76ms1M-row ORDER BY ts DESC LIMIT 10 (was 1.2s, 680×)
- 1.5msDiskANN tail latency p99 (was 30ms, same recall tier)
- 4.4×50-table open 77ms → 17.6ms (dirty checkpoint 42 → 24.6ms)
- 3 轮pre-release audits, 10 issues fixed
Built for embodied-AI workloads
Not a trimmed general-purpose embedded database — every capability is shaped by the real anatomy of robotics data.
Multimodal native
VECTOR(n) columns with indexed KNN, byte-exact BLOB equality, full-text search and TIME_BUCKET aggregation — one SQL engine, one transactional view.
Three forms, one experience
Capture into a high-performance directory, ship as a single CRC-verified zstd snapshot, deploy as a read-only container — chained by one SQL statement.
Embedded zero-ops
No server, no port, no sidecar process. The library file IS the database; corrupt indexes self-heal from source on open.
Power-fail safe kernel
temp+fsync+rename atomic publish, group-commit WAL, orphan-segment adoption — continuously validated by crash injection and differential fuzzing.
Prebuilt on five platforms
Official binaries for macOS (arm64/x64), Linux (x64/arm64) and Windows — cross-compiled and smoke-tested per platform in CI.
Fleet friendly
Incremental snapshot re-export, multi-reader read-only containers, monotonic id space — designed for one coordinator and a hundred collectors.
One SQL across every modality
Vectors, time series, full text, binary — not four databases, but four column types in one table. Real queries look like this:
-- 5 semantically nearest rows in the pose table (index-accelerated) SELECT ts, sid FROM poses ORDER BY emb <-> [0.1, 0.2, 0.3, 0.4] LIMIT 5;
-- 60-second window aggregation + automatic TTL expiry SELECT TIME_BUCKET('60s', ts) AS bucket, AVG(v), MAX(v) FROM poses GROUP BY bucket; ALTER TABLE poses SET TTL = '30d';
-- Hybrid retrieval: full text (BM25) × vector (KNN), RRF fusion db.hybrid_search( "docs_body", # full-text index "joint calibration", # text query "docs_emb", # vector column [0.1, 0.4, 0.2, 0.9], k=10)
-- BLOB byte-exact equality + one-shot MCAP import SELECT id FROM frames WHERE payload = X'DEADBEEF'; IMPORT MCAP 'session_2026_10_17.mcap';
-- Whole database → single file (CRC-verified + zstd) EXPORT DB TO 'fleet.mote' COMPRESSED; -- Deploy side: open read-only, multiple readers co-exist db = Database.open_readonly("fleet.mote")
// All syntax is real — same as repository tests, not mockups
Three forms of data, one pipeline
Embodied data moves through capture, transport and deployment. Each stage wants a different disk shape — MoteDB gives each its optimum, chained by SQL.
High-performance directory
Continuous writes on-robot. Atomic temp+rename publish with group-commit WAL — power loss is routine, not exceptional. Bounded fixed overhead.
Single-file snapshot
Pack the whole database with one statement. Per-file CRC32, optional zstd, friendly to lossy links.
Read-only container
Firmware bundles one file; open() queries immediately. Every write path refused; readers co-exist; maps ship with releases.
Why not glue one together
A SQLite extension for vectors, hand-written SQL for time series, another install for full text — three stores, three consistency models, three ops burdens. MoteDB puts the vector database, the time-series database and full-text search back into one table.
| Capability | MoteDB | SQLite + extensions | Files + custom scripts |
|---|---|---|---|
| Vector KNN (index-accelerated) | ● | ▲ via extension | — |
| Time-series semantics (TIME_BUCKET / TTL / LATEST BY) | ● | ▲ hand-written SQL | — |
| Full-text search (BM25 + snippet) | ● | ● FTS5 | — |
| All modalities in one transactional view | ● | — no cross-extension transactions | — |
| Single-file snapshot (CRC + zstd + incremental) | ● | — manual copy | — |
| Read-only container deploy (multi-reader) | ● | — | — |
| Power-fail safety (crash-injection tested) | ● | ▲ implementation-dependent | ▲ implementation-dependent |
← scroll sideways →
* Comparison based on public capabilities as of 2026-10 and reproducible checks in this repository. ● full · ▲ partial/requires assembly · — not supported
Designed for the AI stack — and readable by AI
The downstream of embodied intelligence is AI: semantic retrieval, training pipelines, agents. MoteDB builds these in rather than leaving them to the user.
Hybrid retrieval (RRF fusion)
BM25 keywords × vector semantics fused by Reciprocal Rank Fusion in one call — semantic query out of the box, no custom rank-merging.
Arrow straight to training pipelines
query_arrow() returns a canonical pyarrow.Table — vector columns as FixedSizeList<float32>, zero-copy into PyTorch/DataLoader.
Readable by AI
llms.txt + JSON-LD structured data + a machine-readable capability manifest — LLMs, agents and AI search can accurately answer "can MoteDB do X".
# Semantic hybrid search: BM25 × KNN, RRF fusion res = db.hybrid_search("docs_body", "joint calibration", "docs_emb", [0.1,0.4,0.2,0.9], k=10) # Results straight to Arrow → zero-copy into the training pipeline tbl = db.query_arrow("SELECT ts, sid, emb FROM poses") # tbl vector column is FixedSizeList<float32> — feed a DataLoader directly
5 minutes: from MCAP to a queryable time-series store
- Multimodal by declaration: TIMESERIES(ts) semantics, VECTOR(4) columns
- Parameterized writes with prepared-statement caching
- Familiar <-> operator for vector KNN, index-accelerated
- Reopen just works: WAL replay + segment migration + index self-heal
# pip install motedb-python from motedb import Database db = Database("robot.mote") db.execute("CREATE TABLE poses ( ts TIMESTAMP, sid INT, emb VECTOR(4) ) TIMESERIES(ts)") db.executemany("INSERT INTO poses VALUES (?,?,?)", poses) # Vector KNN: 5 nearest poses hits = db.query("SELECT ts, sid FROM poses ORDER BY emb <-> [0.1,0.2,0.3,0.4] LIMIT 5") # Transport: pack the whole database into one snapshot file db.execute("EXPORT DB TO 'fleet.mote'")
Every line written for edge devices, validated to kernel standards
Edge failures cannot be rolled back or hot-fixed remotely. So releases pass through these gates — not marketing numbers, reproducible checks in the repository.
Three official SDKs, one set of semantics
Value mapping out of the box: vectors ↔ arrays, BLOB ↔ bytes, timestamps ↔ microseconds. No third-party half-bindings.
Documentation
Maintained in-repository, versioned with the code.
MIT open source · Run it today
No server, no port, no lock-in — one library file is your multimodal database.