Skip to content

HeliosDB Architecture

HeliosDB Architecture

System Architecture Diagram

┌─────────────────────────────────────────────────────────────────┐
│ Client Applications │
│ (Python, Java, Go - PostgreSQL/MySQL wire protocols) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Protocol Gateway Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │PostgreSQL│ │ MySQL │ │Snowflake │ │ Pinecone │ │
│ │ Handler │ │ Handler │ │ HTTP │ │ Vector │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Compute Layer │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Query Planner & Optimizer │ │
│ │ - SQL Parsing │ │
│ │ - Predicate Pushdown Analysis │ │
│ │ - Partition Pruning │ │
│ │ - Distributed Plan Generation │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Query Executor │ │
│ │ - Physical Operators (Scan, Filter, Join, Aggregate) │ │
│ │ - Result Merging │ │
│ │ - Cache Management │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ Compute Nodes: Stateless, Elastic, Multi-tenant │
└─────────────────────────────────────────────────────────────────┘
▼ HIDB Protocol (gRPC over RDMA)
┌─────────────────────────────────────────────────────────────────┐
│ Storage Layer │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Shard 1 │ │ Shard 2 │ │ Shard N │ │
│ │ │ │ │ │ │ │
│ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │
│ │ │ LSM Engine │ │ │ │ LSM Engine │ │ │ │ LSM Engine │ │ │
│ │ │ │ │ │ │ │ │ │ │ │ │ │
│ │ │ Memtable │ │ │ │ Memtable │ │ │ │ Memtable │ │ │
│ │ │ SSTables │ │ │ │ SSTables │ │ │ │ SSTables │ │ │
│ │ │ CommitLog │ │ │ │ CommitLog │ │ │ │ CommitLog │ │ │
│ │ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │
│ │ │Predicate │ │ │ │Predicate │ │ │ │Predicate │ │ │
│ │ │Filter Engine│ │ │ │Filter Engine│ │ │ │Filter Engine│ │ │
│ │ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │ │
│ │ │Vector Index │ │ │ │Vector Index │ │ │ │Vector Index │ │ │
│ │ │(HNSW/IVF) │ │ │ │(HNSW/IVF) │ │ │ │(HNSW/IVF) │ │ │
│ │ └─────────────┘ │ │ └─────────────┘ │ │ └─────────────┘ │ │
│ │ │ │ │ │ │ │
│ │ Primary: Node A │ │ Primary: Node B │ │ Primary: Node C │ │
│ │ Mirror: Node B │ │ Mirror: Node C │ │ Mirror: Node A │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ │
│ Storage Nodes: Intelligent, Durable, Sharded │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Metadata & Consensus Layer (Raft) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Metadata │ │ Metadata │ │ Metadata │ │
│ │ Node 1 │ │ Node 2 │ │ Node 3 │ │
│ │ (Leader) │ │ (Follower) │ │ (Follower) │ │
│ │ │ │ │ │ │ │
│ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │
│ │ │ Raft Log │ │ │ │ Raft Log │ │ │ │ Raft Log │ │ │
│ │ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │ │
│ │ │ │ │ │ │ │
│ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │
│ │ │ Topology │ │ │ │ Topology │ │ │ │ Topology │ │ │
│ │ │ Schema │ │ │ │ Schema │ │ │ │ Schema │ │ │
│ │ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ Managed State: Shard Map, Schema, Node Status │
└─────────────────────────────────────────────────────────────────┘

Data Flow

Write Path

Client
▼ SQL INSERT
Compute Node (Query Planner)
▼ Determine Shard (Consistent Hash)
Storage Node (Primary)
├─▶ Write to CommitLog (durability)
├─▶ Insert into Memtable (in-memory)
└─▶ Replicate to Mirror (sync)
└─▶ Mirror acknowledges
└─▶ Return success to client

Read Path (Point Query)

Client
▼ SQL SELECT WHERE key=?
Compute Node (Query Planner)
├─▶ Check local cache
│ └─▶ HIT: Return
└─▶ MISS: Route to shard
Storage Node
├─▶ Check Memtable
│ └─▶ FOUND: Return
├─▶ Check Immutable Memtables
│ └─▶ FOUND: Return
└─▶ Check SSTables (with Bloom filter)
├─▶ Bloom MISS: Skip SSTable
└─▶ Bloom HIT: Read SSTable
└─▶ Return to compute
└─▶ Return to client

Analytical Query with Predicate Pushdown

Client
▼ SQL SELECT * FROM table WHERE col > 100
Compute Node
├─▶ Parse & Optimize
│ └─▶ Identify pushable predicates
├─▶ Build PredicatePushdownRequest
│ ├─▶ predicates: [col > 100]
│ └─▶ projection: [col1, col2, col3]
└─▶ Dispatch to all relevant shards (parallel)
Storage Nodes (parallel execution)
├─▶ Apply predicates locally
│ ├─▶ Scan SSTables (HCC compressed)
│ ├─▶ Decompress only needed columns
│ └─▶ Filter rows
└─▶ Stream FilteredResultSet
Compute Node
├─▶ Merge results from all shards
├─▶ Apply remaining operations
│ (joins, aggregates, sort)
└─▶ Return to client
Client
▼ SQL SELECT * FROM docs
WHERE vector_similarity(embedding, ?) < 0.1
AND category = 'tech'
Compute Node
├─▶ Extract query vector
├─▶ Build VectorSearchRequest
│ ├─▶ query_vector: [0.1, 0.2, ...]
│ ├─▶ predicates: [category = 'tech']
│ └─▶ top_k: 10
└─▶ Dispatch to shards
Storage Nodes
├─▶ Build allow-list from predicates
│ └─▶ Bitmap: category='tech' rows
├─▶ Traverse HNSW index
│ ├─▶ Check allow-list before distance calc
│ └─▶ Multi-hop for filtered islands
└─▶ Return VectorSearchResult
Compute Node
├─▶ Merge top-k from all shards
├─▶ Re-rank globally
└─▶ Return to client

Component Interactions

Compute ↔ Storage (HIDB Protocol)

// Compute sends
PredicatePushdownRequest {
table_id: 1,
partition_ids: [1, 2, 3],
predicates: [
Predicate::GreaterThan { col_id: 0, value: 100 }
],
projection_columns: [0, 1, 2],
}
// Storage responds
FilteredResultSet {
rows: [
Row { values: [101, "data1", "value1"] },
Row { values: [102, "data2", "value2"] },
],
has_more: false,
}

Primary ↔ Mirror (Replication)

// Primary sends
ReplicationDataStream {
shard_id: 1,
sequence: 1001,
entries: [
ReplicationEntry {
key: b"key1",
value: Some(b"value1"),
timestamp: 12345,
}
],
}
// Mirror acknowledges
ReplicationAck {
shard_id: 1,
sequence: 1001,
status: Success,
}

Metadata ↔ Compute (Topology Updates)

// Metadata broadcasts
CacheInvalidationNotice {
table_id: 1,
affected_keys: [b"key1", b"key2"],
transaction_id: 9999,
}
// Compute updates cache
local_cache.invalidate(&notice.affected_keys);

Sharding Strategy

Consistent Hash Ring

Virtual Node Distribution:
─────────────────────────────────────────────────
Hash Ring (0 to 2^64)
─────────────────────────────────────────────────
0% 25% 50% 75% 100%
│ │ │ │ │
├──────┼──────┼──────┼──────┤
│ N1 │ N2 │ N3 │ N1 │ (Physical nodes)
│ │ │ │ │
├──┬──┬┼──┬──┬┼──┬──┬┼──┬──┬┤
│v1│v2││v1│v2││v1│v2││v1│v2││ (Virtual nodes)
└──┴──┴┴──┴──┴┴──┴──┴┴──┴──┴┘
Key Routing:
hash(key) = 0x3A... → Maps to N2 (primary)
→ Next node N3 (mirror)

Shard Replication

Shard 1:
┌─────────────┐ sync ┌─────────────┐
│ Primary │ ─────────────▶│ Mirror │
│ (Node A) │ ◀──────────── │ (Node B) │
└─────────────┘ ack └─────────────┘
│ │
│ │
└──────────┬───────────────────┘
┌─────────────┐
│ Witness │
│ (Quorum) │
└─────────────┘
Failover:
- Mirror loses connection to Primary
- Mirror checks Witness
- Witness confirms Primary down
- 2/3 quorum achieved
- Mirror promotes to Primary

Storage Engine Internals

LSM-tree Structure

┌────────────────────────────────────────┐
│ Active Memtable │
│ BTreeMap<Key, Entry> (64MB) │
│ - Sorted by key │
│ - In-memory, fast writes │
└────────────────────────────────────────┘
│ (threshold reached)
┌────────────────────────────────────────┐
│ Immutable Memtables (queue) │
│ - Frozen for flushing │
│ - Still readable │
└────────────────────────────────────────┘
│ (background flush)
┌────────────────────────────────────────┐
│ SSTables (on-disk) │
│ │
│ SSTable-0000001.sst (newest) │
│ ┌──────────────────────────────────┐ │
│ │ Data Block 1 │ │
│ │ Data Block 2 │ │
│ │ ... │ │
│ │ Bloom Filter │ │
│ │ Metadata (min/max key) │ │
│ └──────────────────────────────────┘ │
│ │
│ SSTable-0000002.sst │
│ SSTable-0000003.sst (oldest) │
└────────────────────────────────────────┘
│ (compaction)
┌────────────────────────────────────────┐
│ Compacted SSTables (merged) │
│ - Remove duplicates │
│ - Discard tombstones │
│ - Larger, fewer files │
└────────────────────────────────────────┘

Commit Log Format

┌──────────────────────────────────────────────┐
│ Entry 1 │
│ ┌──────────┬──────────────────────────────┐ │
│ │ Length │ Serialized LogEntry │ │
│ │ (4 bytes)│ (bincode) │ │
│ └──────────┴──────────────────────────────┘ │
│ │
│ Entry 2 │
│ ┌──────────┬──────────────────────────────┐ │
│ │ Length │ Serialized LogEntry │ │
│ │ (4 bytes)│ (bincode) │ │
│ └──────────┴──────────────────────────────┘ │
│ │
│ ... (sequential append-only) │
└──────────────────────────────────────────────┘
LogEntry::Put {
key: Bytes,
value: Bytes,
timestamp: u64,
}

Module Dependency Graph

main.rs
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
heliosdb- heliosdb- heliosdb-
compute storage metadata
│ │ │
└──────┬───────┴───────┬──────┘
│ │
▼ ▼
heliosdb- heliosdb-
network common
│ │
└───────┬───────┘
heliosdb-vector
(External: hnsw crate)

Deployment Topology

┌─────────────────────────────────────────────────┐
│ Load Balancer │
│ (Protocol Router) │
└─────────────────────────────────────────────────┘
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│Compute 1│ │Compute 2│ │Compute N│
└─────────┘ └─────────┘ └─────────┘
│ │ │
└──────────────┼──────────────┘
│ HIDB Protocol
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│Storage 1│───▶│Storage 2│───▶│Storage 3│
│(Primary)│ │(Mirror) │ │(Primary)│
└─────────┘ └─────────┘ └─────────┘
│ │ │
└──────────────┼──────────────┘
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│Metadata │ │Metadata │ │Metadata │
│ Node 1 │◀──▶│ Node 2 │◀──▶│ Node 3 │
│(Leader) │ │ │ │ │
└─────────┘ └─────────┘ └─────────┘

Scaling Dimensions

Compute Scale-Out

  • Add more compute nodes for higher query concurrency
  • Stateless, can be spun up/down dynamically
  • Shared-nothing architecture

Storage Scale-Out

  • Add more storage nodes for capacity
  • Consistent hashing automatically rebalances
  • Data migration happens in background

Metadata Scale-Up

  • Fixed cluster size (3 or 5 nodes)
  • Raft leader handles writes
  • All nodes handle reads

This architecture provides:

  • Separation of concerns: Compute, storage, and metadata independent
  • Linear scalability: Add nodes for capacity or throughput
  • Fault tolerance: Replication at every layer
  • Performance: Intelligent storage with predicate pushdown
  • Flexibility: Multi-protocol support for diverse clients