High-Performance Embedded Document Database
Built in Rust. Wrapped for Node.js. Zero configuration, in-process, single file, pure ACID.
Oblivinx3x is a MongoDB-compatible embedded database providing ACID transactions, MVCC concurrency control, and a state-of-the-art Hybrid B+/LSM storage architecture — all executing right inside your Node.js process.
Rust Engine
Maximum performance via Neon FFI. Zero-copy where possible. Memory-safe by design.
ACID & MVCC
Snapshot Isolation ensures readers never block writers. Full rollback support with savepoints.
MQL Compatible
MongoDB Query Language: $match, $group, $lookup, $facet, $bucket, window functions, and more.
Quick Start
Install and start using Oblivinx3x in under a minute. No Rust toolchain needed.
# Install via npm
npm install oblivinx3x
import { Oblivinx3x } from 'oblivinx3x';
// Open or create a database
const db = new Oblivinx3x('data.ovn', {
compression: 'lz4',
bufferPool: '256MB'
});
const users = db.collection('users');
// Insert
await users.insertOne({
name: 'Alice',
role: 'admin',
age: 28
});
// Query
const admins = await users.find({ role: 'admin' });
// Close
await db.close();
Features Overview
| Category | Feature | Status |
|---|---|---|
| Storage | B+ Tree (Primary Index) | ✅ |
| MemTable + SSTable (LSM) | ✅ | |
| WAL with Crash Recovery | ✅ | |
| Segmented LRU Buffer Pool | ✅ | |
| Blob Storage (Chunked) | ✅ | |
| LZ4 / Zstd Compression | ✅ | |
| Query | MQL Filter Operators (20+) | ✅ |
| Update Operators (16+) | ✅ | |
| Aggregation Pipeline (18+ stages) | ✅ | |
| Cost-based Query Planner | ✅ | |
| Index-accelerized lookups | ✅ | |
| Indexes | Secondary Indexes (Single/Compound) | ✅ |
| AHIT (Adaptive Hybrid Index Tree) | ✅ | |
| Full-Text Search (TF-IDF) | ✅ | |
| Vector Search (Cosine Similarity) | ✅ | |
| Geospatial (R-Tree, $geoWithin, $near) | ✅ | |
| ACID | MVCC Snapshot Isolation | ✅ |
| Savepoints (Partial Rollback) | ✅ | |
| Session Idempotency (Retryable Writes) | ✅ | |
| Write-Write Conflict Detection | ✅ | |
| Advanced | Views (Logical + Materialized) | ✅ |
| Relations / Foreign Keys | ✅ | |
| Triggers (before/after events) | ✅ | |
| Change Streams (Real-time) | ✅ | |
| Attached Databases | ✅ | |
| Document Versioning (Time Travel) | ✅ | |
| Pragmas (Runtime Config) | ✅ | |
| Security | Access Control (RBAC) | ✅ |
| Field-Level ACL | ✅ | |
| Audit Logging | ✅ | |
| Input Validation + Rate Limiter | ✅ | |
| Utils | ID Generation (UUID/Snowflake/Increment) | ✅ |
| Safe Serialization (Depth Guard) | ✅ |
Database API
The Oblivinx3x class is the main entry point. It manages database lifecycle, collections,
transactions, and advanced features.
Constructor
new Oblivinx3x(path: string, options?: OvnConfig)
OvnConfig Options
| Option | Type | Default | Description |
|---|---|---|---|
pageSize |
number |
4096 | Page size in bytes (power of 2, 512–65536) |
bufferPool |
string |
'256MB' | Buffer pool size ('64MB', '256MB', '1GB') |
readOnly |
boolean |
false | Open in read-only mode |
compression |
'none'|'lz4'|'zstd' |
'none' | Storage compression algorithm |
walMode |
boolean |
true | Enable Write-Ahead Log (always on) |
Methods
collection<T>(name) — Get collection referencecreateCollection(name, options?) — Create collection
explicitlydropCollection(name) — Drop collectionlistCollections() — List all collection namesbeginTransaction() — Start MVCC transactionputBlob(data) / getBlob(uuid) — Blob storagecheckpoint() — Force flush to diskgetMetrics() / getVersion() — Observabilityexport() / backup(path) — Export/backupclose() — Graceful closeCollection API
MongoDB-compatible CRUD interface with generic type support.
Insert
await users.insertOne({ name: 'Alice' });
await users.insertMany([{ name: 'Bob' }, { name: 'Carol' }]);
Query
await users.find({ age: { $gte: 18 } }, { sort: { name: 1 }, limit: 10 });
await users.findOne({ email: 'alice@example.com' });
await users.countDocuments({ active: true });
await users.exists({ role: 'admin' }); // NEW: boolean shorthand
Update
await users.updateOne({ name: 'Alice' }, { $set: { age: 29 } });
await users.updateMany({ active: false }, { $set: { active: true } });
await users.findOneAndUpdate({ name: 'Alice' }, { $inc: { loginCount: 1 } }); // NEW
Delete
await users.deleteOne({ name: 'Alice' });
await users.deleteMany({ expired: true });
await users.findOneAndDelete({ temp: true }); // NEW
Index Management
await users.createIndex({ age: 1 }, { unique: true });
await users.createIndex({ title: 'text', content: 'text' }); // Full-text
await users.dropIndex('age_1');
await users.hideIndex('temp_idx'); // Hide without dropping
await users.unhideIndex('temp_idx');
Transactions (MVCC)
Full ACID transactions with Snapshot Isolation. Readers never block writers. Savepoints enable partial rollback.
const txn = await db.beginTransaction();
try {
await txn.update('accounts', { _id: 'alice' }, { $inc: { bal: -100 } });
await txn.update('accounts', { _id: 'bob' }, { $inc: { bal: 100 } });
// Savepoint for partial rollback
await txn.savepoint('before_risky');
await txn.insert('logs', { msg: 'risky op' });
await txn.commit();
} catch (err) {
await txn.rollback(); // Idempotent — safe in finally blocks
throw err;
}
Transaction API
insert(collection, doc) — Insert within transactioninsertMany(collection, docs) — Batch insertupdate(collection, filter, update) — Update documentsdelete(collection, filter) — Delete documentssavepoint(name) — Create checkpointrollbackToSavepoint(name) — Undo to checkpointreleaseSavepoint(name) — Remove checkpointcommit() / rollback() — LifecycleQuery Builder
Fluent, chainable API for building complex queries.
const results = await users.find()
.where({ age: { $gte: 18 } })
.project({ name: 1, email: 1 })
.sort({ name: 1 })
.limit(20)
.skip(10)
.toArray();
// Streaming cursor for large datasets
const cursor = users.find().where({ active: true }).cursor({ batchSize: 100 });
for await (const user of cursor) {
console.log(user.name);
}
Filter Operators
Full MongoDB Query Language (MQL) filter support.
| Category | Operators |
|---|---|
| Comparison | $eq $ne $gt $gte $lt
$lte $in $nin |
| Logical | $and $or $not $nor |
| Array | $all $elemMatch $size |
| Element | $exists $type |
| Regex | $regex |
| Geospatial | $geoWithin $near $geoNear |
| Text | $text { $search: "..." } |
| Expression | $expr { $gt: ["$field1", "$field2"] } |
Update Operators
| Category | Operators |
|---|---|
| Field | $set $unset $rename |
| Arithmetic | $inc $mul |
| Conditional | $min $max |
| Array | $push $push + $each $pull $pullAll
$addToSet $addToSet + $each $pop |
| Temporal | $currentDate |
| Upsert | $setOnInsert |
Aggregation Pipeline
MongoDB-compatible multi-stage pipeline with 18+ stages and 9 accumulator types.
Supported Stages
$matchFilter
documents$groupGroup + accumulators$projectField reshaping$sort / $limit / $skipOrdering & pagination$unwindFlatten
arrays$lookupLeft join
$countDocument
count$facetMulti-pipeline$bucket / $bucketAutoBucketing$addFields / $setAdd/update fields$replaceRoot / $replaceWithReplace root$merge / $outWrite results$setWindowFieldsWindow functions$graphLookupGraph traversalAccumulators
$sum $avg $min $max $first
$last $push $addToSet $count
const stats = await orders.aggregate([
{ $match: { status: 'completed' } },
{ $group: {
_id: '$region',
total: { $sum: '$amount' },
avgOrder: { $avg: '$amount' }
}},
{ $sort: { total: -1 } },
{ $limit: 5 }
]);
Secondary Indexes & AHIT
Secondary indexes are backed by the Adaptive Hybrid Index Tree (AHIT) — a self-optimizing structure that keeps hot entries in RAM and cold entries on disk.
AHIT Mechanics
- Hot Zone: In-memory B+ tree for frequently accessed entries
- Cold Zone: Disk-backed BTreeMap (SSTable simulation) for infrequent data
- Promotion: Cold→Hot after 1000 accesses within 60s window
- Demotion: Hot→Cold when access drops below 100/60s
- SCO Bitmap: Skip-Column Optimization for compound index keys
Index Types
createIndex({ field: 1 }) — Single ascendingcreateIndex({ a: 1, b: -1 }) — Compound
(leftmost prefix matching)createIndex({ field: 1 }, { unique: true }) — Unique constraintcreateIndex({ field: 'text' }) — Full-text searchcreateIndex({ field: 1 }, { hidden: true }) — Hidden (maintained but not used by
planner)Full-Text Search
Inverted index with tokenization, English stemming, and TF-IDF scoring.
// Create full-text index
await articles.createIndex({ title: 'text', content: 'text' });
// Search with $text operator
const results = await articles.find({
$text: { $search: 'database performance' }
});
Pipeline
Unicode word segmentation → Lowercase → Suffix stemming (-ing, -tion, -ness, -ment, -ly, -es, -ed, -s) → Token → Posting list with position tracking → TF-IDF scoring
Vector Search
Approximate/exact nearest neighbor search using cosine similarity on vector embeddings.
// Create vector index
await embeddings.createVectorIndex('vector', {
dimensions: 1536,
metric: 'cosine'
});
// Search
const similar = await embeddings.vectorSearch(
[0.1, 0.2, /* ... 1536 dims */],
10, // limit
{ category: 'science' } // optional filter
);
Geospatial
R-Tree based 2D spatial indexing for GeoJSON Point, LineString, Polygon, or [lng, lat] arrays.
// Create 2dsphere index
await restaurants.createGeoIndex('location');
// $geoWithin — bounding box
const nearby = await restaurants.find({
location: {
$geoWithin: {
$centerSphere: [[-73.935, 40.731], 5 / 3963.2] // 5 mile radius
}
}
});
Autocomplete
Case-insensitive prefix search on indexed string fields.
const suggestions = await users.autocomplete('name', 'ali', 5);
// Returns: Alice, Ali, Alina, etc.
Storage Architecture
Hybrid B+/LSM Engine
Writes flow through a Write-Ahead Log (WAL) into an in-memory MemTable (SkipList). When the MemTable reaches its threshold (default 64MB), it freezes and flushes to Level-0 SSTables. Background compaction merges SSTables into a persistent B+ Tree for optimal read performance.
WAL Crash Recovery
Every write is logged with CRC32 checksums. On restart, the engine detects the WAL active flag, finds the last checkpoint position, and replays all records after it. Group commit and fsync ensure durability.
Buffer Pool (Segmented LRU)
Pages are cached in two segments: probationary (new) and protected (frequently accessed). Eviction prioritizes unpinned probationary pages. Dirty pages are tracked and flushed on checkpoint.
SSTable + Bloom Filter
Each SSTable includes a Bloom filter (7 hash functions, ~1% false positive rate) for O(1) negative lookups. L0 tables are scanned newest-first. Compaction triggers at L0 count ≥ 4.
Blob Storage
Store large binary files (images, videos, documents) directly in the storage engine. Blobs are chunked into 256KB pages for efficient streaming.
const fs = await import('node:fs/promises');
const buffer = await fs.readFile('video.mp4');
const blobId = await db.putBlob(buffer);
console.log(`Saved blob: ${blobId}`);
const data = await db.getBlob(blobId);
if (data) await fs.writeFile('output.mp4', data);
Views
Logical views are stored queries that always read live data. Materialized views precompute results for faster reads.
// Logical view
await db.createView('active_users', {
source: 'users',
pipeline: [
{ $match: { active: true } },
{ $project: { name: 1, email: 1 } }
]
});
// Materialized view with scheduled refresh
await db.createView('daily_stats', {
source: 'orders',
pipeline: [{ $group: { _id: '$date', total: { $sum: 1 } } }],
materializedOptions: { refresh: 'scheduled', schedule: '0 0 * * *' }
});
Relations & Foreign Keys
Define foreign-key-like relationships between collections with configurable referential integrity.
await db.defineRelation({
from: 'posts.user_id',
to: 'users._id',
type: 'many-to-one',
onDelete: 'cascade', // Delete posts when user is deleted
onUpdate: 'restrict', // Prevent updating referenced user._id
indexed: true // Auto-create index on posts.user_id
});
// Set integrity mode: 'off' | 'soft' | 'strict'
await db.setReferentialIntegrity('strict');
Triggers
Execute JavaScript handlers on document events: beforeInsert, afterInsert, beforeUpdate, afterUpdate, beforeDelete, afterDelete.
await db.createTrigger('users', 'beforeInsert', async (doc, ctx) => {
if (!doc.email) throw new Error('email is required');
doc.createdAt = Date.now();
return doc;
});
Document Versioning (Time Travel)
Natively track full document history, compute granular diffs, and perform non-destructive rollbacks.
// 1. Enable tracking
await users.enableVersioning({
mode: 'diff',
maxVersions: 50
});
// 2. Operations are saved as versions
await users.updateOne({ _id: 'u1' }, { $set: { role: 'admin' } });
// 3. View history and diffs
const history = await users.listVersions('u1');
const diff = await users.diffVersions('u1', 1, 2);
// 4. Rollback safely (creates a new version!)
await users.rollbackToVersion('u1', 1);
Versioning API
enableVersioning(config) — Start tracking versionslistVersions(docId) — Get version historygetVersion(docId, ver) — Get specific revisiondiffVersions(docId, v1, v2) — Compute changes between versionsrollbackToVersion(docId, ver) — Safe restore by appendingtagVersion(docId, ver, tag) / restoreFromTag(docId, tag) — LabelingChange Streams
Real-time event streaming using MPSC channels. Events include Insert, Update, Replace, Delete, and Invalidate.
// Database-level watch
const dbStream = db.watch();
dbStream.on('change', (event) => {
console.log(event.opType, event.namespace, event.fullDocument);
});
// Collection-level watch (filtered)
const colStream = users.watch();
colStream.on('change', (event) => {
console.log('User changed:', event.opType);
});
Pragmas
Runtime configuration directives that persist across sessions in the Metadata Segment.
await db.pragma('foreign_keys', true);
await db.pragma('synchronous', 'full');
await db.pragma('cache_size', '1GB');
const mode = await db.pragma('synchronous'); // Read
Available Pragmas
foreign_keys synchronous auto_vacuum cache_size
page_size journal_mode referential_integrity
cross_db_transactions wal_checkpoint optimize
integrity_check max_savepoint_depth materialized_view_size
Attached Databases
Attach additional .ovn files with aliases for cross-database queries.
await db.attach('analytics.ovn', 'analytics');
// Query attached database collections via aliased namespace
await db.detach('analytics');
const attached = await db.listAttached();
Access Control & ACL
Built-in security primitives for multi-tenant environments.
import { SecurityContext, checkPermission } from 'oblivinx3x';
const sec = new SecurityContext({
permissions: new Map([
['users', new Set(['read', 'write'])],
['admin_logs', new Set(['read'])]
]),
rateLimit: { reads: 100, writes: 50 },
inputValidation: { maxDocumentDepth: 20, maxDocumentSize: 16 * 1024 * 1024 }
});
// Check permission
if (checkPermission(sec.permissions, 'users', 'read')) {
// Allowed
}
Field-Level ACL
Control read/write access per field. Use filterDocumentByACL for reads and
sanitizeDocumentByACL for writes.
Audit Logging
Immutable append-only log of database operations for compliance and debugging.
import { AuditLogger } from 'oblivinx3x';
const auditor = new AuditLogger({
enabled: true,
events: ['insert', 'update', 'delete']
});
auditor.log({
operation: 'insert',
collection: 'users',
documentId: 'uuid-123',
sessionId: 'sess-abc'
});
Input Validation
Protect against NoSQL injection and oversized payloads.
import { sanitizeInput, validateDepth, validateSize } from 'oblivinx3x';
// Validate document depth (default max: 20)
validateDepth(doc, 20);
// Validate document size (default max: 16MB)
validateSize(doc, 16 * 1024 * 1024);
// Full sanitization
sanitizeInput(doc, {
maxDocumentDepth: 20,
maxDocumentSize: 16 * 1024 * 1024,
allowedFields: new Map([['users', ['name', 'email', 'age']]])
}, 'users');
Rate Limiter
Token bucket algorithm for per-collection read/write rate limiting.
import { RateLimiter, RateLimitedError } from 'oblivinx3x';
const limiter = new RateLimiter();
limiter.configure({ reads: 100, writes: 50 });
try {
limiter.assertAllowed('users', 'write');
await users.insertOne({ name: 'Alice' });
} catch (err) {
if (err instanceof RateLimitedError) {
console.log('Rate limit exceeded — try again later');
}
}
Utilities & ID Generation
ID Strategies
import { generateId } from 'oblivinx3x';
// UUID v4 — random, globally unique
const uuid = generateId('uuid');
// Snowflake — time-ordered, distributed-friendly
const snowflake = generateId('snowflake', {
snowflake: { workerId: 1, datacenterId: 0 }
});
// Auto-increment — per-collection monotonic
const inc = generateId('increment', { collection: 'users' });
Safe Serialization
import { safeSerialize, safeDeserialize, withRetry } from 'oblivinx3x';
// JSON with depth guard and circular reference detection
const json = safeSerialize(doc, 20);
const parsed = safeDeserialize(json);
// Retry with exponential backoff
const result = await withRetry(
() => users.insertOne(doc),
{ maxAttempts: 3, backoffMs: 50 }
);
Export & Backup
// Export as JSON object
const data = await db.export();
console.log(data.users); // Array of documents
// Backup to JSON file (auto-checkpoints first)
await db.backup('backup-2026-04-10.json');
Explain & Diagnostics
// Explain a find query
const plan = await db.explain('users', { age: { $gt: 18 } });
console.log(plan.index); // 'age_1' or null
console.log(plan.scanType); // 'indexScan' | 'collectionScan' | 'coveredScan'
console.log(plan.estimatedCost);
console.log(plan.fallbackReason);
// Explain aggregation pipeline
const aggPlan = await db.explainAggregate('orders', [
{ $match: { status: 'completed' } },
{ $group: { _id: '$region', total: { $sum: 1 } } }
]);
OBE Format (Binary Encoding)
Oblivinx Binary Encoding — the compact binary format for document storage.
Document Structure
4-byte total length → 16-byte UUID → 8-byte txid → 1-byte tombstone flag → Varint field count → Encoded fields
Value Types (16 tags)
Null |
BoolTrue |
BoolFalse |
Int32 |
Int64 |
Float64 |
Varint (LEB128) |
String |
Binary |
Document |
Array |
Timestamp |
ObjectId |
Decimal128 |
BlobRef |
GeoPoint |
GeoJSON |
16 type tags total | ||
Background Workers
Automated maintenance tasks running on configurable intervals.
| Worker | Interval | Description |
|---|---|---|
| Compaction | 30s | Merge L0 SSTables into higher levels |
| GC | 60s | Prune old MVCC versions beyond horizon |
| TTL Expire | 60s | Delete documents past their expireAfterSeconds |
| Checkpoint | 120s | Flush MemTable + WAL checkpoint |
| Buffer Eviction | 10s | Evict cold pages from segmented LRU |
| Change Stream GC | 300s | Clean closed subscriber channels |
Error Codes
| Code | Class | Description |
|---|---|---|
ERR_DATABASE_CLOSED |
DatabaseClosedError |
Operation on closed database |
ERR_COLLECTION_NOT_FOUND |
CollectionNotFoundError |
Collection does not exist |
ERR_COLLECTION_EXISTS |
CollectionExistsError |
Collection already exists |
ERR_DUPLICATE_KEY |
DuplicateKeyError |
Unique constraint violation |
ERR_TRANSACTION_ABORTED |
TransactionAbortedError |
Transaction was aborted |
ERR_TRANSACTION_CONFLICT |
TransactionConflictError |
Write-write conflict detected |
ERR_SAVEPOINT_NOT_FOUND |
SavepointNotFoundError |
Savepoint does not exist |
ERR_SAVEPOINT_EXISTS |
SavepointExistsError |
Savepoint name conflict |
ERR_PERMISSION_DENIED |
PermissionDeniedError |
Insufficient permissions |
ERR_RATE_LIMITED |
RateLimitedError |
Rate limit exceeded |
ERR_INPUT_TOO_DEEP |
InputDepthError |
Document nesting depth exceeded |
ERR_INPUT_TOO_LARGE |
InputSizeError |
Document size exceeds limit |
ERR_SERIALIZATION |
SerializationError |
JSON serialization failed |
ERR_NOT_IMPLEMENTED |
NotImplementedError |
Feature not yet implemented |
ERR_CORRUPT_DATA |
CorruptDataError |
Data corruption detected |