Skip to main content
Version: 0.4.0

SochDB Complete Architecture & API Reference

Version: 0.3.1
License: Apache-2.0
Repository: https://github.com/sochdb/sochdb


Table of Contents​

  1. Design Philosophy
  2. Executive Summary
  3. System Architecture
  4. Module Structure
  5. Storage Engine
  6. Client SDK API
  7. TOON Format Internals
  8. MCP Protocol & Tools API
  9. Vector Search API
  10. Transaction & MVCC API
  11. Context Query API
  12. Query Processing Pipeline
  13. Memory Management
  14. Concurrency Model
  15. Python SDK Architecture
  16. Performance Characteristics
  17. Configuration Reference

Design Philosophy​

SochDB is built around four core principles:

1. Token Efficiency First​

Every design decision prioritizes minimizing tokens when data is consumed by LLMs:

Traditional: LLM ← JSON ← SQL Result ← Query Optimizer ← B-Tree
~150 tokens for 3 rows

SochDB: LLM ← TOON ← Columnar Scan ← Path Resolution
~50 tokens for 3 rows (66% reduction)

2. Path-Based Access​

O(|path|) resolution instead of O(log N) tree traversal:

Path: "users/42/profile/avatar"

TCH Resolution:
β”œβ”€ users β†’ Table lookup (O(1) hash)
β”‚ └─ 42 β†’ Row index (O(1) direct)
β”‚ └─ profile β†’ Column group (O(1))
β”‚ └─ avatar β†’ Column offset (O(1))

Total: O(4) = O(|path|), regardless of table size

3. Columnar by Default​

Read only what you need - 50% I/O reduction for typical queries.

4. Embeddable & Extensible​

Single-file deployment (~1.5MB) with optional plugin architecture.


Executive Summary​

SochDB is an AI-native database designed from the ground up for LLM applications and autonomous agents. Key differentiators:

FeatureDescriptionBenefit
Trie-Columnar Hybrid (TCH)O(|path|) lookups via radix-compressed trieConstant-time path resolution
HNSW/Vamana Vector IndexesScale-aware routing (HNSW <100K, Vamana >1M)Optimal latency at any scale
TOON Format40-60% token reduction vs JSONSignificant LLM cost savings
MCP ProtocolNative LLM tool integrationSeamless agent orchestration
Embedded ArchitectureSQLite-like deployment (single binary)Zero external dependencies

System Architecture​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ SochDB Architecture β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ MCP Server β”‚ β”‚ Agent Ctx β”‚ β”‚ gRPC API β”‚ Interfaces β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Query Processing Engine β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ ToonQL β”‚ β”‚ Context β”‚ β”‚ Token Budgeting β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ Parser β”‚ β”‚ Builder β”‚ β”‚ Engine β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Unified Storage Layer β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ TCH β”‚ β”‚ Vector β”‚ β”‚ MVCC β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ Storage β”‚ β”‚ Index β”‚ β”‚ Transactions β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Durability Layer (WAL) β”‚ β”‚
β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
β”‚ β”‚ β”‚ WAL β”‚ β”‚ Group β”‚ β”‚ Crash β”‚ β”‚ β”‚
β”‚ β”‚ β”‚ Writer β”‚ β”‚ Commit β”‚ β”‚ Recovery β”‚ β”‚ β”‚
β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Design Principles​

  1. Sync-First Storage: Core storage uses synchronous I/O (like SQLite) for predictable latency and simpler embedding
  2. Optional Async: Tokio runtime only required for server mode (MCP, gRPC)
  3. Lock-Free Reads: Hazard pointer protection for true lock-free read paths
  4. AI-Native Formatting: TOON format as first-class output for token efficiency

Module Structure​

Crate Dependency Graph​

sochdb-studio (GUI)
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Application Layer β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ sochdb-mcp β”‚ β”‚sochdb-grpc β”‚ β”‚sochdb-wasm β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–Ό β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Client Layer β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ sochdb β”‚ β”‚ sochdb-python β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Query Layer β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚sochdb-queryβ”‚ β”‚sochdb-toolsβ”‚ β”‚ toon-fmt β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–Ό β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Execution Layer β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚sochdb-indexβ”‚ β”‚sochdb-vectorβ”‚ β”‚sochdb-kernelβ”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–Ό β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Storage Layer β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ sochdb-storage β”‚ β”‚
β”‚ β”‚ (WAL + LSCS + GC) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Core Layer β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ sochdb-core β”‚ β”‚
β”‚ β”‚ (Types, Codec, Trie)β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Crate Responsibilities​

CratePurposeKey Types
sochdb-coreFoundational types, codecs, trieToonValue, ToonSchema, ToonCodec
sochdb-storageWAL, LSCS, GC, durabilityDatabase, WalManager, GarbageCollector
sochdb-kernelQuery execution, table operationsKernel, TableHandle, ScanIterator
sochdb-indexB-tree, learned indexesBTreeIndex, LearnedSparseIndex
sochdb-vectorHNSW, Vamana, PQHnswIndex, VamanaIndex, ProductQuantizer
sochdb-queryToonQL parser, optimizerParser, Planner, Optimizer
sochdbHigh-level SDK, context queriesDurableConnection, ContextQueryBuilder
sochdb-mcpMCP protocol serverMcpServer, ToolExecutor
sochdb-pythonPython bindings (FFI)PySochDB, PyVectorIndex
sochdb-wasmBrowser WASM buildWasmVectorIndex

Storage Engine​

Log-Structured Column Store (LSCS)​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Storage Engine β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ Write-Ahead Log (WAL) β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Active β”‚ β”‚ Sealed β”‚ β”‚ Sealed β”‚ β”‚ Archived β”‚ β”‚
β”‚ β”‚ Segment β”‚ β”‚ Segment β”‚ β”‚ Segment β”‚ β”‚ Segments β”‚ β”‚
β”‚ β”‚ (writes) β”‚ β”‚ (full) β”‚ β”‚ (full) β”‚ β”‚ (backup) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ β–Ό β–Ό β–Ό β–Ό β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Group Commit Buffer β”‚ β”‚
β”‚ β”‚ Batches transactions for efficient fsync β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β”‚ Log-Structured Column Store (LSCS) β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ MemTable β”‚ β”‚ MemTable β”‚ β”‚ MemTable β”‚ β”‚
β”‚ β”‚ (Active) β”‚ β”‚ (Immutable) β”‚ β”‚ (Flushing) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β–Ό β–Ό β–Ό β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Sorted Runs β”‚ β”‚
β”‚ β”‚ L0: β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ (recently flushed) β”‚ β”‚
β”‚ β”‚ L1: β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (merged) β”‚ β”‚
β”‚ β”‚ L2: β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (compacted) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β”‚ Background Workers β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Compactorβ”‚ β”‚ GC β”‚ β”‚Checkpointβ”‚ β”‚
β”‚ β”‚ Thread β”‚ β”‚ Thread β”‚ β”‚ Thread β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Lock-Free MemTable​

The MemTable uses hazard pointers for true lock-free reads:

pub struct LockFreeMemTable {
data: DashMap<Vec<u8>, LockFreeVersionChain>,
hazard_domain: HazardDomain,
size_bytes: AtomicUsize,
}

impl LockFreeMemTable {
/// Read with zero-copy callback (optimal path)
pub fn read_with<F, R>(
&self,
key: &[u8],
snapshot_ts: u64,
txn_id: Option<u64>,
f: F,
) -> Option<R>
where
F: FnOnce(&[u8]) -> R;

/// Write a value (creates uncommitted version)
pub fn write(&self, key: Vec<u8>, value: Option<Vec<u8>>, txn_id: u64) -> Result<()>;

/// Commit a transaction's writes
pub fn commit(&self, txn_id: u64, commit_ts: u64, keys: &[Vec<u8>]);
}

Scalability: Lock-free design achieves 23% better scaling vs RwLock at 8 threads.

SST File Format​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ SST File Structure β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Data Blocks β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Block 0: [key1:val1][key2:val2]...[keyN:valN][trailer] β”‚ β”‚
β”‚ β”‚ Block 1: [key1:val1][key2:val2]...[keyN:valN][trailer] β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Meta Blocks β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Bloom Filter Block β”‚ β”‚
β”‚ β”‚ Column Stats Block β”‚ β”‚
β”‚ β”‚ Compression Dict Block (optional) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Index Block β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ [first_key_0, offset_0, size_0] β”‚ β”‚
β”‚ β”‚ [first_key_1, offset_1, size_1] β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Footer (48 bytes) β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚ β”‚ Meta Index β”‚ Index Handle β”‚ Magic + Version β”‚β”‚
β”‚ β”‚ BlockHandle β”‚ BlockHandle β”‚ β”‚β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Compaction Strategy​

Level 0 (L0): Recent flushes, may overlap
β”Œβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”
β”‚SST1β”‚ β”‚SST2β”‚ β”‚SST3β”‚ β”‚SST4β”‚ ← 4 files, overlapping key ranges
β””β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”˜
β”‚
β–Ό Compaction (merge sort)
Level 1 (L1): Non-overlapping, sorted
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ SST (merged) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό Size-triggered compaction
Level 2 (L2): 10x larger budget
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ SST files β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

WAL Record Format​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ WAL Record Format β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ CRC32 β”‚ Length β”‚ Type β”‚ TxnID β”‚ Data β”‚ β”‚
β”‚ β”‚ (4 bytes)β”‚ (4 bytes)β”‚ (1 byte) β”‚ (8 bytes)β”‚ (variable) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β”‚ Record Types: β”‚
β”‚ β€’ 0x01: PUT (key, value) β”‚
β”‚ β€’ 0x02: DELETE (key) β”‚
β”‚ β€’ 0x03: BEGIN_TXN (txn_id) β”‚
β”‚ β€’ 0x04: COMMIT_TXN (txn_id, commit_ts) β”‚
β”‚ β€’ 0x05: ABORT_TXN (txn_id) β”‚
β”‚ β€’ 0x06: CHECKPOINT (LSN, active_txns) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Recovery Process​

fn recover(&self) -> Result<RecoveryStats> {
// 1. Find latest checkpoint
let checkpoint = self.find_latest_checkpoint()?;

// 2. Replay WAL from checkpoint
let mut wal_reader = WalReader::open_from(checkpoint.lsn)?;
let mut active_txns: HashSet<u64> = checkpoint.active_txns;

while let Some(record) = wal_reader.next()? {
match record.record_type {
RecordType::BeginTxn => {
active_txns.insert(record.txn_id);
}
RecordType::Put => {
if active_txns.contains(&record.txn_id) {
self.replay_put(&record)?;
}
}
RecordType::CommitTxn => {
active_txns.remove(&record.txn_id);
}
RecordType::AbortTxn => {
self.rollback_txn(record.txn_id)?;
active_txns.remove(&record.txn_id);
}
_ => {}
}
}

// 3. Abort incomplete transactions
for txn_id in active_txns {
self.rollback_txn(txn_id)?;
}

Ok(stats)
}

Client SDK API​

ToonClient (In-Memory)​

For testing and development without durability requirements:

use sochdb::prelude::*;

// Open database
let client = ToonClient::open("./mydb")?;

// Configure token budget for LLM responses
let client = client.with_token_budget(4096);

// Path-based queries (O(|path|) resolution)
let result = client.query("/users/123").execute()?;

// Execute ToonQL
let rows = client.execute("SELECT * FROM users WHERE active = true")?;

// Begin transaction
let txn = client.begin()?;

// Vector operations
let vectors = client.vectors("embeddings")?;
vectors.add(&["doc1", "doc2"], &[vec1, vec2])?;
let results = vectors.search(&query_embedding, 10)?;

DurableToonClient (Production)​

Full WAL/MVCC support for production workloads:

use sochdb::prelude::*;

// Open with durability
let client = DurableToonClient::open("./mydb")?;

// Path-based CRUD
client.put("/users/123", b"{\"name\": \"Alice\"}")?;
let data = client.get("/users/123")?;
client.delete("/users/123")?;

// Scan with prefix
let results = client.scan("/users/")?;

// Transaction support
client.begin()?;
client.put("/users/1", value1)?;
client.put("/users/2", value2)?;
let commit_ts = client.commit()?;

// Force durability
client.fsync()?;

PathQuery Builder​

Leverages TCH's O(|path|) resolution:

use sochdb::path_query::{PathQuery, CompareOp};

// Fluent query builder
let results = client.query("/users")
.filter("score", CompareOp::Gt, ToonValue::Int(80))
.filter("active", CompareOp::Eq, ToonValue::Bool(true))
.select(&["name", "email", "score"])
.order_by("score", SortDirection::Desc)
.limit(10)
.execute()?;

Comparison Operators​

pub enum CompareOp {
Eq, // =
Ne, // !=
Lt, // <
Le, // <=
Gt, // >
Ge, // >=
Like, // LIKE pattern matching
In, // IN (array)
IsNull, // IS NULL
IsNotNull, // IS NOT NULL
}

Output Formats​

pub enum OutputFormat {
Toon, // Default: 40-60% fewer tokens than JSON
Json, // Standard JSON for compatibility
Columnar, // Raw columnar for analytics
}

TOON Format Internals​

Text Format Grammar​

document     ::= table_header newline row*
table_header ::= name "[" count "]" "{" fields "}" ":"
row ::= value ("," value)* newline
value ::= null | bool | number | string | array | ref

null ::= "βˆ…"
bool ::= "T" | "F"
number ::= integer | float
string ::= raw_string | quoted_string
array ::= "[" value ("," value)* "]"
ref ::= "ref(" identifier "," integer ")"

Binary Format Structure​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ TOON Binary Format β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Header (16 bytes) β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Magic β”‚ Version β”‚ Flags β”‚ Row Countβ”‚ β”‚
β”‚ β”‚ (4 bytes)β”‚ (2 bytes)β”‚ (2 bytes)β”‚ (8 bytes)β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Schema Section β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Name Len β”‚ Table Name (UTF-8) β”‚ β”‚
β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚
β”‚ β”‚ Col Countβ”‚ [Column Definitions...] β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Data Section (columnar) β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Column 0: [type_tag][values...] β”‚ β”‚
β”‚ β”‚ Column 1: [type_tag][values...] β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Type Tags​

#[repr(u8)]
pub enum ToonTypeTag {
Null = 0x00,
False = 0x01,
True = 0x02,
PosFixint = 0x10, // 0-15 in lower nibble
NegFixint = 0x20, // -16 to -1 in lower nibble
Int8 = 0x30,
Int16 = 0x31,
Int32 = 0x32,
Int64 = 0x33,
Float32 = 0x40,
Float64 = 0x41,
FixStr = 0x50, // 0-15 char length in lower nibble
Str8 = 0x60,
Str16 = 0x61,
Str32 = 0x62,
Array = 0x70,
Ref = 0x80,
}

Varint Encoding​

fn encode_varint(mut value: u64, buf: &mut Vec<u8>) {
while value >= 0x80 {
buf.push((value as u8) | 0x80);
value >>= 7;
}
buf.push(value as u8);
}

fn decode_varint(buf: &[u8]) -> (u64, usize) {
let mut result = 0u64;
let mut shift = 0;
for (i, &byte) in buf.iter().enumerate() {
result |= ((byte & 0x7F) as u64) << shift;
if byte & 0x80 == 0 {
return (result, i + 1);
}
shift += 7;
}
(result, buf.len())
}

MCP Protocol & Tools API​

Server Lifecycle​

Client                           Server
β”‚ β”‚
│──── initialize ──────────────►│
β”‚ β”‚ Create SochDB connection
│◄─── capabilities ─────────────│
β”‚ β”‚
│──── initialized ─────────────►│
β”‚ β”‚
│──── tools/list ──────────────►│
β”‚ β”‚ Return 15 built-in tools
│◄─── tool definitions ─────────│
β”‚ β”‚
│──── tools/call ──────────────►│
β”‚ { "name": "sochdb_query", β”‚
β”‚ "arguments": {...} } β”‚
β”‚ β”‚ Execute query
│◄─── result (TOON format) ─────│

MCP Server Implementation​

impl McpServer {
pub fn new(conn: Arc<EmbeddedConnection>) -> Self;

/// Dispatch JSON-RPC request
pub fn dispatch(&self, req: &RpcRequest) -> RpcResponse;

/// Get database statistics
pub fn db_stats(&self) -> DatabaseStats;
}

Built-in Tools Reference​

Core Database Tools​

ToolDescriptionRequired Args
sochdb_context_queryAI-optimized context with token budgetingsections
sochdb_queryExecute ToonQL queryquery
sochdb_getGet value at pathpath
sochdb_putSet value at pathpath, value
sochdb_deleteDelete at pathpath
sochdb_list_tablesList tables with metadata-
sochdb_describeGet table schematable

Memory Tools (Episode/Entity Schema)​

ToolDescriptionRequired Args
memory_search_episodesSemantic episode searchquery
memory_get_episode_timelineEvent timeline for episodeepisode_id
memory_search_entitiesEntity searchquery
memory_get_entity_factsEntity detailsentity_id
memory_build_contextOne-shot context packinggoal, token_budget

Log Tools​

ToolDescriptionRequired Args
logs_tailGet last N rowstable
logs_timelineTime-range querytable, start, end

Tool Schemas​

sochdb_context_query​

{
"name": "sochdb_context_query",
"description": "Fetch AI-optimized context from SochDB with token budgeting",
"inputSchema": {
"type": "object",
"properties": {
"sections": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"kind": { "type": "string", "enum": ["literal", "get", "last", "search"] },
"text": { "type": "string", "description": "For kind=literal" },
"path": { "type": "string", "description": "For kind=get" },
"table": { "type": "string", "description": "For kind=last/search" },
"query": { "type": "string", "description": "For kind=search" },
"top_k": { "type": "integer", "default": 10 }
},
"required": ["name", "kind"]
}
},
"token_budget": { "type": "integer", "default": 4096 },
"format": { "type": "string", "enum": ["toon", "json", "markdown"], "default": "toon" },
"truncation": { "type": "string", "enum": ["tail_drop", "head_drop", "proportional"], "default": "tail_drop" }
},
"required": ["sections"]
}
}

sochdb_query​

{
"name": "sochdb_query",
"description": "Execute a ToonQL query. Returns results in TOON format.",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "ToonQL query" },
"format": { "type": "string", "enum": ["toon", "json"], "default": "toon" },
"limit": { "type": "integer", "default": 100 }
},
"required": ["query"]
}
}

memory_search_episodes​

{
"name": "memory_search_episodes",
"description": "Search for similar past episodes by semantic similarity",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "Natural language query" },
"k": { "type": "integer", "default": 5 },
"episode_type": {
"type": "string",
"enum": ["conversation", "task", "workflow", "debug", "agent_interaction"]
},
"entity_id": { "type": "string", "description": "Filter by entity" }
},
"required": ["query"]
}
}

memory_build_context​

{
"name": "memory_build_context",
"description": "Build optimized LLM context from memory automatically",
"inputSchema": {
"type": "object",
"properties": {
"goal": { "type": "string", "description": "What the context will be used for" },
"token_budget": { "type": "integer", "default": 4096 },
"session_id": { "type": "string" },
"episode_id": { "type": "string" },
"entity_ids": { "type": "array", "items": { "type": "string" } },
"include_schema": { "type": "boolean", "default": false }
},
"required": ["goal", "token_budget"]
}
}

Vector Search API​

Scale-Aware Router​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Scale-Aware Routing β”‚
β”‚ β”‚
β”‚ Vectors < 100K ─────► HNSW (in-memory, low latency) β”‚
β”‚ Vectors 100K-1M ────► Hybrid (HNSW + Vamana migration) β”‚
β”‚ Vectors > 1M ───────► Vamana + PQ (disk-based, scalable) β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

VectorCollection API​

pub struct VectorCollection {
dimension: usize,
backend: VectorBackend,
pq: Option<ProductQuantizer>,
id_map: RwLock<HashMap<String, usize>>,
reverse_map: RwLock<HashMap<usize, String>>,
}

impl VectorCollection {
/// Open or create a vector collection
pub fn open(conn: &ToonConnection, name: &str) -> Result<Self>;

/// Add vectors in batch
pub fn add(&mut self, ids: &[&str], vectors: &[Vec<f32>]) -> Result<()>;

/// Add a single vector
pub fn add_one(&mut self, id: &str, vector: Vec<f32>) -> Result<()>;

/// Search for nearest neighbors
pub fn search(&self, query: &[f32], k: usize) -> Result<Vec<SearchResult>>;

/// Get vector by ID
pub fn get(&self, id: &str) -> Option<Vec<f32>>;

/// Delete vector by ID
pub fn delete(&mut self, id: &str) -> Result<bool>;

/// Get collection statistics
pub fn stats(&self) -> VectorStats;

/// Get compression ratio (if PQ trained)
pub fn compression_ratio(&self) -> Option<f32>;

/// Migrate batch during idle time (for hybrid mode)
pub fn migrate_batch(&mut self) -> Result<usize>;
}

pub struct SearchResult {
pub id: String,
pub distance: f32,
pub metadata: Option<Value>,
}

pub struct VectorStats {
pub count: usize,
pub dimension: usize,
pub backend: String,
pub memory_bytes: usize,
pub pq_enabled: bool,
pub migration_progress: Option<f32>,
}

Index Parameters​

HNSW (Small Collections <100K)​

ParameterDefaultDescription
M16Max connections per node
M_max032Max connections at layer 0
ef_construction200Build-time search width
ef_search100Query-time search width
Memory~1.5KB/vecHigher memory, lowest latency
Latency<1msSub-millisecond queries

Vamana (Large Collections >1M)​

ParameterDefaultDescription
R64Graph out-degree
L100Search list size
Ξ±1.2Pruning parameter
Memory~0.5KB/vec + mmapDisk-friendly
Latency2-5msGood for large scale

Product Quantizer (Compression)​

ParameterDefaultDescription
M8Number of subquantizers
Ksub256Centroids per subquantizer
nbits8Bits per code
Memory32B/vec96% compression for 768d

HNSW Graph Structure​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ HNSW Graph Structure β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”‚
β”‚ Layer 2: ●───────────────────────● β”‚
β”‚ β”‚ β”‚ β”‚
β”‚ Layer 1: ●───●───────●───────────●───────● β”‚
β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
β”‚ Layer 0: ●───●───●───●───●───●───●───●───●───●───● β”‚
β”‚ v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 β”‚
β”‚ β”‚
β”‚ Search: Start at top layer, greedily descend β”‚
β”‚ Insert: Random level, connect at each layer β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Level Generation Algorithm​

/// Per HNSW paper: level = floor(-ln(uniform(0,1)) * mL)
fn random_level(&self) -> usize {
let uniform: f32 = rand::random();
let level = (-uniform.ln() * self.level_multiplier).floor() as usize;
level.min(16) // Cap at 16 layers
}

// Distribution for M=16, mLβ‰ˆ0.36:
// P(level=0) β‰ˆ 70%
// P(level=1) β‰ˆ 21%
// P(level=2) β‰ˆ 6%
// P(levelβ‰₯3) β‰ˆ 3%

Search Algorithm​

fn search_internal(&self, query: &[f32], k: usize) -> Vec<(u64, f32)> {
let entry_point = self.entry_point?;

// Navigate from top layer to layer 1
let mut current = entry_point;
for layer in (1..=self.max_layer).rev() {
current = self.search_layer_single(query, current, layer);
}

// Search layer 0 with ef_search candidates
let candidates = self.search_layer(query, current, self.ef_search.max(k), 0);

// Return top-k results
candidates.into_iter()
.take(k)
.map(|(dist, idx)| (self.nodes[idx].id, dist))
.collect()
}

WASM Vector Index (Browser)​

import init, { WasmVectorIndex } from 'sochdb-wasm';

async function main() {
await init();

// Create index: dimension=768, M=16, ef_construction=100
const index = new WasmVectorIndex(768, 16, 100);

// Insert vectors
const ids = BigUint64Array.from([1n, 2n, 3n]);
const vectors = new Float32Array(768 * 3);
const inserted = index.insertBatch(ids, vectors);

// Search
const query = new Float32Array(768);
const results = index.search(query, 10);
}

Transaction & MVCC API​

Transaction Lifecycle​

// Begin transaction
client.begin()?;

// Operations within transaction
client.put("/users/1", value1)?;
client.put("/users/2", value2)?;
let data = client.get("/users/1")?;

// Commit or abort
let commit_ts = client.commit()?; // Returns commit timestamp
// OR
client.abort()?; // Discard all changes

Isolation Levels​

pub enum IsolationLevel {
ReadCommitted, // See committed data at statement start
RepeatableRead, // See committed data at transaction start
Serializable, // SSI - Full serializability
}

// Begin with specific isolation
let txn = client.begin_with_isolation(IsolationLevel::Serializable)?;

MVCC Internals​

Version chain structure:

pub struct LockFreeVersion {
storage: VersionStorage, // Inline (&lt;48B) or heap
txn_id: AtomicU64, // Writing transaction
commit_ts: AtomicU64, // Commit timestamp (0 if uncommitted)
next: AtomicPtr<LockFreeVersion>, // Next older version
}

Visibility rules:

  • Own writes: Visible if txn_id matches current transaction
  • Committed writes: Visible if commit_ts <= snapshot_ts
  • Conflict detection: SSI validation checks for rw-antidependency cycles

MVCC Version Chain​

struct VersionedValue {
value: Option<Vec<u8>>, // None = tombstone
txn_id: u64, // Transaction that wrote this
timestamp: u64, // Commit timestamp
next: Option<Box<VersionedValue>>, // Older versions
}

impl MVCCStore {
fn get(&self, key: &Key, snapshot_ts: u64) -> Option<&[u8]> {
let mut version = self.current.get(key)?;

// Find visible version
while version.timestamp > snapshot_ts {
version = version.next.as_ref()?;
}

version.value.as_deref()
}
}

Group Commit Optimization​

/// Optimal batch size: N* = √(2 Γ— L_fsync Γ— Ξ» / C_wait)
struct GroupCommitBuffer {
pending: VecDeque<PendingCommit>,
config: GroupCommitConfig,
}

impl GroupCommitBuffer {
fn optimal_batch_size(&self, arrival_rate: f64, wait_cost: f64) -> usize {
let l_fsync = self.config.fsync_latency_us as f64 / 1_000_000.0;
let n_star = (2.0 * l_fsync * arrival_rate / wait_cost).sqrt();
(n_star as usize).clamp(1, self.config.max_batch_size)
}
}

Context Query API​

ContextQueryBuilder​

Build AI-optimized context with automatic token budgeting:

pub struct ContextQueryBuilder {
sections: Vec<ContextSection>,
token_budget: usize,
format: ContextFormat,
truncation: TruncationStrategy,
}

pub enum SectionKind {
Literal { text: String },
Get { path: String },
Last { table: String, top_k: usize, filter: Option<Filter> },
Search { query: String, collection: String, top_k: usize },
ToolRegistry { include_schema: bool },
}

pub enum TruncationStrategy {
TailDrop, // Drop lowest priority sections first
HeadDrop, // Drop highest priority sections first
Proportional, // Reduce all sections proportionally
}

Usage Example​

let context = ContextQueryBuilder::new()
.section("system", SectionKind::Literal {
text: "You are a helpful assistant.".to_string()
})
.section("history", SectionKind::Last {
table: "messages".to_string(),
top_k: 10,
filter: None,
})
.section("knowledge", SectionKind::Search {
query: user_message.clone(),
collection: "docs".to_string(),
top_k: 5,
})
.with_budget(4096)
.with_format(ContextFormat::Toon)
.with_truncation(TruncationStrategy::TailDrop)
.execute()?;

TOON Format Token Savings​

JSON (52 chars β‰ˆ 13 tokens):
{"user":{"name":"Alice","age":30,"active":true}}

TOON (47 chars β‰ˆ 12 tokens, 8% savings):
user.name="Alice" user.age=30 user.active=true

TOON Table Format (40%+ savings for arrays):
[users]
name | age | active
"Alice" | 30 | true
"Bob" | 25 | false

Performance Characteristics​

Complexity Analysis​

OperationSochDBB-Tree (SQLite)Notes
Point ReadO(|path|)O(log N)TCH path-based
Point WriteO(|path|)O(log N)+ WAL
Range ScanO(|path| + K)O(log N + K)K = result count
Vector Search (HNSW)O(log N)N/Aef-dependent
Vector Search (Vamana)O(log N)N/A+ PQ overhead
Full ScanO(N)O(N)Columnar advantage

Memory Budget​

ComponentDefaultConfiguration
MemTable64MBmemtable_size
Block Cache128MBblock_cache_size
HNSW Index~1.5KB/vecM, ef_construction
Vamana Index~0.5KB/vecR, L, Ξ±
PQ Codes32B/vecM, Ksub
WAL Buffer16MBwal_buffer_size

Latency Targets​

OperationTargetP99
Point Read (cached)<100ΞΌs<500ΞΌs
Point Read (disk)<1ms<5ms
Point Write<100ΞΌs<1ms
Transaction Commit<1ms<5ms
Vector Search (10K)<1ms<5ms
Vector Search (1M)<10ms<50ms
Context Query<50ms<200ms

Configuration Reference​

DatabaseConfig​

pub struct DatabaseConfig {
// WAL settings
pub wal_segment_size: usize, // Default: 64MB
pub wal_sync_mode: SyncMode, // Fsync, FsyncDelayed, None
pub group_commit: bool, // Batch commits for throughput
pub group_commit_delay_us: u64, // Max wait time

// LSCS settings
pub memtable_size: usize, // Default: 64MB
pub level_ratio: usize, // Default: 10
pub max_levels: usize, // Default: 7

// GC settings
pub gc_interval_secs: u64, // Default: 60
pub min_versions_to_keep: usize, // Default: 2
}

ClientConfig​

pub struct ClientConfig {
/// Maximum tokens per response (for LLM context management)
pub token_budget: Option<usize>,
/// Enable streaming output
pub streaming: bool,
/// Default output format
pub output_format: OutputFormat,
/// Connection pool size
pub pool_size: usize,
}

SyncMode Options​

pub enum SyncMode {
Fsync, // fsync after every commit (safest)
FsyncDelayed, // fsync after group_commit_delay_us
None, // No fsync (fastest, risk of data loss)
}

Workspace Dependencies​

Key dependencies from Cargo.toml:

[workspace.dependencies]
# Serialization
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
bincode = "1.3"

# Compression
lz4 = "1.24"
zstd = "0.13"

# Data structures
crossbeam-skiplist = "0.1"
parking_lot = "0.12"
dashmap = "5.5"

# Hashing
blake3 = "1.5"
twox-hash = "1.6"

# Vectors
ndarray = "0.15"

# Error handling
thiserror = "1.0"
anyhow = "1.0"

# Async (optional)
tokio = { version = "1.35", optional = true }

Query Processing Pipeline​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Query Pipeline β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1. PARSE β”‚
β”‚ Input: conn.query("users").where_eq("status", "active") β”‚
β”‚ Output: QueryAST { table, predicates, projections } β”‚
β”‚ β”‚
β”‚ 2. PLAN β”‚
β”‚ β€’ Choose access method (scan vs index) β”‚
β”‚ β€’ Push down predicates β”‚
β”‚ Output: LogicalPlan β”‚
β”‚ β”‚
β”‚ 3. OPTIMIZE β”‚
β”‚ β€’ Cost-based index selection β”‚
β”‚ β€’ Predicate ordering by selectivity β”‚
β”‚ Output: PhysicalPlan β”‚
β”‚ β”‚
β”‚ 4. EXECUTE β”‚
β”‚ β€’ Open column readers β”‚
β”‚ β€’ Apply predicates (vectorized) β”‚
β”‚ Output: QueryResult β”‚
β”‚ β”‚
β”‚ 5. FORMAT β”‚
β”‚ β€’ TOON: users[N]{cols}:row1;row2;... β”‚
β”‚ β€’ JSON: [{"col": val}, ...] β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Predicate Pushdown​

fn push_predicates(plan: &mut ScanPlan, predicates: &[Predicate]) {
for pred in predicates {
match pred {
// Push to index lookup
Predicate::Eq(col, val) if is_indexed(col) => {
plan.index_lookup = Some(IndexLookup { column: col, value: val });
}
// Push to block-level filtering
Predicate::Range(col, min, max) => {
plan.block_filters.push(BlockFilter { column: col, min, max });
}
// Late filter (after scan)
_ => plan.late_filters.push(pred.clone()),
}
}
}

Memory Management​

Buddy Allocator​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Buddy Allocator β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Order 10 (1KB): [β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ] β”‚
β”‚ β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ Order 9 (512B): [β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ] [________________] β”‚
β”‚ β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β” β”‚
β”‚ Order 8 (256B): [β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ] [β–ˆβ–ˆβ–ˆβ–ˆ] ... β”‚
β”‚ β”‚
β”‚ Allocation: Find smallest power-of-2 block, split if needed β”‚
β”‚ Deallocation: Coalesce with buddy if both free β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Arena Allocator​

struct BuddyArena {
buddy: BuddyAllocator,
current_block: Mutex<Option<ArenaBlock>>,
block_size: usize,
}

impl BuddyArena {
fn allocate(&self, size: usize, align: usize) -> Result<usize> {
let mut current = self.current_block.lock();

// Try current block first
if let Some(ref mut block) = *current {
let aligned = (block.offset + align - 1) & !(align - 1);
if aligned + size <= block.size {
block.offset = aligned + size;
return Ok(block.base + aligned);
}
}

// Allocate new block from buddy allocator
let new_size = size.max(self.block_size).next_power_of_two();
let base = self.buddy.allocate(new_size)?;
*current = Some(ArenaBlock { base, offset: size, size: new_size });
Ok(base)
}

fn reset(&self) {
// Free all blocks at once - O(1) reset
self.current_block.lock().take();
}
}

Concurrency Model​

Lock Hierarchy​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Lock Acquisition Order β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1. Catalog Lock (RwLock) - Table schema changes β”‚
β”‚ 2. Table Lock (per-table RwLock) - DDL operations β”‚
β”‚ 3. Transaction Manager Lock (Mutex) - Begin/commit/abort β”‚
β”‚ 4. WAL Lock (Mutex) - Append to write-ahead log β”‚
β”‚ 5. Memtable Lock (RwLock) - In-memory writes β”‚
β”‚ 6. Index Lock (per-index RwLock) - Index modifications β”‚
β”‚ β”‚
β”‚ ALWAYS acquire in this order to prevent deadlocks β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Lock-Free Reads via MVCC​

impl Database {
fn read(&self, key: &[u8], snapshot: Snapshot) -> Option<Value> {
// No locks needed - snapshot isolation
let version = self.mvcc.get_visible(key, snapshot.timestamp);
version.map(|v| v.value.clone())
}
}

// Snapshot is just a timestamp
struct Snapshot {
timestamp: u64,
txn_id: u64,
}

Python SDK Architecture​

Access Modes​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Python Application β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ sochdb (PyPI) β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ Embedded β”‚ β”‚ IPC β”‚ β”‚ Bulk API β”‚ β”‚
β”‚ β”‚ FFI β”‚ β”‚ Client β”‚ β”‚ (subprocess β†’ sochdb-bulk) β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ β”‚ β”‚
β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
β”‚ Rust β”‚ β”‚ IPC β”‚ β”‚ sochdb-bulk β”‚
β”‚ FFI β”‚ β”‚ Server β”‚ β”‚ binary β”‚
β”‚ (.so) β”‚ β”‚ β”‚ β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Distribution Model (uv-style wheels)​

Wheels contain pre-built Rust binaries - no compilation required:

sochdb-0.2.3-py3-none-manylinux_2_17_x86_64.whl
β”œβ”€β”€ sochdb/
β”‚ β”œβ”€β”€ __init__.py
β”‚ β”œβ”€β”€ database.py # Embedded FFI
β”‚ β”œβ”€β”€ ipc.py # IPC client
β”‚ β”œβ”€β”€ bulk.py # Bulk operations
β”‚ └── _bin/
β”‚ └── linux-x86_64/
β”‚ └── sochdb-bulk # Pre-built binary

Platform matrix:

  • manylinux_2_17_x86_64 - Linux glibc β‰₯ 2.17
  • manylinux_2_17_aarch64 - Linux ARM64
  • macosx_11_0_universal2 - macOS Intel + Apple Silicon
  • win_amd64 - Windows x64

Bulk API FFI Bypass​

For vector-heavy workloads, the Bulk API avoids FFI overhead:

Python FFI path (130 vec/s):
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” memcpy β”Œβ”€β”€β”€β”€β”€β”€β”
β”‚ numpy β”‚ ────────────→│ Rust β”‚ β†’ repeated N times
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ per batch β””β”€β”€β”€β”€β”€β”€β”˜

Bulk API path (1,600 vec/s):
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” mmap β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” fork β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ numpy β”‚ ────────→ β”‚ temp file β”‚ ────────→ β”‚ sochdb-bulk β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 1 write β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 1 proc β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Result: 12Γ— throughput improvement for bulk vector operations.


Summary​

SochDB's architecture delivers:

  1. AI-Native Design:

    • TOON format (40-60% token savings)
    • Context queries with automatic token budgeting
    • MCP integration for seamless LLM tool use
  2. Embedded Simplicity:

    • SQLite-like deployment (~1.5MB binary)
    • Sync-first storage for predictable latency
    • Zero external dependencies
  3. Scale-Aware Adaptation:

    • HNSW for small collections (<100K vectors, <1ms latency)
    • Vamana+PQ for large collections (>1M vectors, 32B/vector)
    • Automatic migration between backends
  4. Production-Ready:

    • WAL durability with group commit
    • MVCC transactions with SSI isolation
    • Crash recovery with checkpoint/replay
  5. High Performance:

    • O(|path|) lookups via TCH (Trie-Columnar Hybrid)
    • Lock-free reads via hazard pointers
    • 12Γ— Python throughput via Bulk API

This enables SochDB to replace the traditional AI stack (PostgreSQL + Pinecone + Redis + custom RAG) with a single, optimized system.