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 reference
createCollection(name, options?) — Create collection explicitly
dropCollection(name) — Drop collection
listCollections() — List all collection names
beginTransaction() — Start MVCC transaction
putBlob(data) / getBlob(uuid) — Blob storage
checkpoint() — Force flush to disk
getMetrics() / getVersion() — Observability
export() / backup(path) — Export/backup
close() — Graceful close

Collection 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 transaction
insertMany(collection, docs)Batch insert
update(collection, filter, update)Update documents
delete(collection, filter)Delete documents
savepoint(name)Create checkpoint
rollbackToSavepoint(name)Undo to checkpoint
releaseSavepoint(name)Remove checkpoint
commit() / rollback()Lifecycle

Query 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 traversal

Accumulators

$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 ascending
createIndex({ a: 1, b: -1 })Compound (leftmost prefix matching)
createIndex({ field: 1 }, { unique: true })Unique constraint
createIndex({ field: 'text' })Full-text search
createIndex({ 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 versions
listVersions(docId)Get version history
getVersion(docId, ver)Get specific revision
diffVersions(docId, v1, v2)Compute changes between versions
rollbackToVersion(docId, ver)Safe restore by appending
tagVersion(docId, ver, tag) / restoreFromTag(docId, tag)Labeling

Change 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