matteobovetti/vairedb

VaireDB is a cloud native, high performance distributed analytical database.

Rust

14

68 commits

updated Sep 21, 2026

See the code

See what people are saying (2)

SourceMessageScoreDate

VaireDB, I'm looking for Rust OSS contributors (r/rust)

Hello! I started this hobby projects some months ago, VaireDB is a analytical database that aim to scale DuckDB using Data Fusion as a distributed query engine. On top we have PostgreSQL wire protocol, so any PGSQL clients can interact with VaireDB. The project is starting growing a lot in term of…

0

Sep 22, 2026

VarieDB, a cloud native, high performance distributed analytical database. (r/rust)

I would like to share a personal project (first made with Rust), where I have tried to scale DuckDB as a shard level core node, with Data Fusion and PostgreSQL wire protocol on top. [https://github.com/matteobovetti/vairedb](https://github.com/matteobovetti/vairedb) Note: It's a personal project…

0

Sep 22, 2026

README

VaireDB

VaireDB is a cloud native, distributed SQL database that combines PostgreSQL wire compatibility, with DuckDB's columnar vectorized execution engine for high-throughput analytical workloads across a horizontally scalable cluster.

Read the When use VaireDB section for understanding where VaireDB is best suited for your use cases.

[!IMPORTANT]
VaireDB is currently under active development. Breaking changes may occur and major features may be added. Consider this a work in progress and not yet ready for production use. Any contributions are welcome for targeting the production-ready v1.0 release.

Overview

VaireDB exposes a unified SQL interface through the PostgreSQL wire protocol (v3), allowing connections from any standard PostgreSQL client (psql, JDBC, etc.). Under the hood, data is hash-sharded across core nodes, each running an embedded DuckDB instance optimized for OLAP queries.

Key characteristics:

  • PostgreSQL-compatible SQL via DataFusion parser with automatic dialect translation to DuckDB.
  • Horizontal scalability through hash sharding across core nodes (range sharding planned).
  • Analytical performance powered by DuckDB's columnar vectorized engine.
  • Fault tolerance with configurable replication factor and quorum-based writes.
  • Column pseudonymization for compliance: declared columns are HMAC-SHA256 hashed in the coordinator so plaintext never reaches storage.
  • Operational simplicity as self-contained Rust binaries with YAML configuration.

When use VaireDB

Use Cases

  • CQRS read side — an analytical database positioned close to microservices' transactional databases, serving the query (read) side of a CQRS architecture. Transactional systems keep handling writes in their own stores, while VaireDB absorbs the heavy read and aggregation traffic that would otherwise contend with operational workloads — keeping write paths fast and read paths scalable.

  • Shared read model — a denormalized, read-optimized view of data shared across a microservices ecosystem. Instead of each service repeatedly joining and reshaping data from many sources, VaireDB holds a consolidated, query-friendly representation that teams can reuse, reducing duplicated effort and keeping cross-service reporting consistent.

  • Data fabric or micro-fabric — deployable both as a wide data fabric spanning the whole ecosystem and as a micro-fabric local to each bounded context. The same engine scales from a single bounded context to an organization-wide layer, so you can start small within one domain and grow toward a shared analytical backbone without changing technology.

  • Compliance datastore — supporting data take-out (export), deletion, and anonymization. By centralizing a queryable copy of data, VaireDB makes it easier to satisfy regulatory obligations such as subject-access exports, right-to-be-forgotten deletions, and anonymization, without hunting through every individual service store.

Architecture

VaireDB follows a coordinator/worker topology:

┌──────────────────────────────────────────────────┐
│                   Clients                         │
│            (psql, JDBC, any PG driver)           │
└──────────────────────┬───────────────────────────┘
                       │ PostgreSQL wire protocol (port 5432)
                       ▼
┌──────────────────────────────────────────────────┐
│               Coordinator Node                    │
│  ┌─────────┐ ┌────────┐ ┌──────────────────┐    │
│  │ Catalog │ │ Router │ │ Ballista Sched.  │    │
│  └─────────┘ └────────┘ └──────────────────┘    │
└──────┬───────────────┬───────────────────────────┘
       │ gRPC writes   │ reads (Ballista)
       ▼               ▼
┌────────────┐  ┌────────────┐  ┌────────────┐
│ Core Node  │  │ Core Node  │  │ Core Node  │
│  (DuckDB)  │  │  (DuckDB)  │  │  (DuckDB)  │
└────────────┘  └────────────┘  └────────────┘
  • Coordinator handles client connections, SQL parsing, query planning, metadata management, and dispatching work to core nodes.
  • Core Nodes store data in DuckDB, execute shard-local queries, and replicate writes.

For full details, see the Architecture Documentation.

Project Documentation

VaireDB Documentation

System Design Documentation

All documentation lives under docs/, split into architecture references, feature designs, and testing notes.

Architecture (docs/specs/):

DocumentDescription
Architecture IndexTop-level index with references to all architecture sections
OverviewWhat VaireDB is and its high-level value proposition
Design GoalsGoals and non-goals for the current version
System ArchitectureHigh-level topology and node types
Core Node (DuckDB)Embedded DuckDB engine, storage, and query execution
Coordinator NodeQuery routing, distributed planning, and metadata catalog
Data DistributionSharding strategy and replication
Cluster CoordinationNode discovery, leader election, failure detection
Communication LayerProtocols, wire formats, client interface
Distributed Query ProcessingQuery lifecycle and optimization
Transactions and ConsistencyConsistency model and distributed transactions
Fault Tolerance and RecoveryWAL, snapshotting, node recovery, quorum
SQL Compatibility StatusThe per-axis status of PostgreSQL compatibility, summarized from the gap census
SQL Gap AnalysisWhat a PostgreSQL client cannot fully do against VaireDB today
RoadmapRoadmap for next releases
GlossaryTerm definitions
LinksExternal references

Features (docs/features/):

DocumentDescription
ComplianceData pseudonymization, take-out, and deletion for regulated environments

Getting Started

Prerequisites

  • Rust 1.95 or later (2024 edition)
  • Protobuf compiler (protoc) for gRPC code generation
  • Make for build automation

Building

# Debug build
make build

# Release build
make build-release

# Type-check only (faster feedback loop)
make check

Running Locally - Binary

Start the coordinator:

make run-coordinator

In a separate terminal, start a core node:

make run-core

Connect with any PostgreSQL client:

psql -h localhost -p 5432

Running Locally - Docker Compose

Start a small VaireDB cluster (1 coordinator + 5 core node):

make e2e-up

Stop the small VaireDB cluster:

make e2e-down

Configuration

Configuration uses YAML files with environment-based overlays:

config/
├── coordinator/
│   └── config.yml   # Default coordinator configurations
└── core/
    └── config.yml   # Default core configurations

Default ports:

PortService
5432PostgreSQL wire protocol (client connections)
50040Coordinator gRPC (node registration, heartbeats)
50041Core node gRPC (write dispatch)
50050Ballista scheduler (distributed query execution)

Contributing

Project Layout

vairedb/
├── config/                    # YAML configuration files
├── crates/
│   ├── vairedb-coordinator/   # Coordinator node binary
│   ├── vairedb-core/          # Core node binary
│   └── vairedb-common/        # Shared protobuf code, config, scan plans
├── docker/                    # Dockers file
├── docs/                      # Architecture and testing documentation
├── proto/vairedb/v1/          # Protobuf service definitions
├── tests/e2e/                 # E2E tests
└── Makefile                   # Build automation

Development Workflow

# Format code
make fmt

# Run linter (clippy, fails on warnings)
make lint

# Run all tests
make test

# Run tests for a single crate
cargo test --package vairedb-coordinator

# Run a specific test
cargo test --package vairedb-coordinator -- test_name

# Run E2E tests
make e2e

# Generate code coverage
make coverage

Key Modules

Coordinator (crates/vairedb-coordinator/src/):

ModuleResponsibility
anonymizationColumn pseudonymization: HMAC-SHA256 hashing and in-statement rewriting of declared columns before writes leave the coordinator
catalogPersistent metadata catalog (tables, shards, nodes, anonymization secrets) exposed as a store and as queryable virtual tables
channel_poolConnection pool for gRPC channels to core nodes
column_typesRead-path mapping from a catalog-declared column type to the Arrow type (and PostgreSQL OID) the coordinator advertises for it
configYAML configuration loading
errorCoordinator error types and their mapping to wire error codes
node_servicegRPC NodeService (register/heartbeat/report) and the heartbeat-based failure detector
pgwire_handlerPostgreSQL wire-protocol handler: the single SQL parse and read-path AST rewrites, statement classification and table-name extraction, query routing, DDL/DML execution, result encoding, and catalog introspection
replicationQuorum writes plus a background retry/backoff loop that tails missed writes to lagging replicas
schedulerEmbedded Ballista scheduler: distributed read planning, plan codecs, and shard-affinity task distribution
write_routerResolves shards and dispatches writes to core nodes
write_sql_clWrite-path-only compatibility layer: PostgreSQL-dialect rewriting to DuckDB-compatible form plus shard-routing decisions
utilCross-cutting helpers (epoch timestamps, shard-local table naming)

Core Node (crates/vairedb-core/src/):

ModuleResponsibility
ballista_execBallista executor for distributed SELECT
configYAML configuration loading
engineDuckDB instance management
errorCore node error types
heartbeatRegistration and periodic heartbeats to coordinator
table_providerCustom DataFusion ExecutionPlan that runs shard-local SQL against DuckDB shards
write_queueBounded channel serializing writes to DuckDB
write_servicegRPC service receiving DML from coordinator, with dedup cache and param conversion

Shared (crates/vairedb-common/src/):

Code that must be identical on both sides of the wire. A distributed stage crosses the wire naming its functions, and the executor resolves those names in its own registry, so every function whose PostgreSQL semantics differ from the engine default is implemented once here and registered on every node that plans or executes a read.

ModuleResponsibility
avg_udafPostgreSQL-exact avg over integer columns: numeric at PostgreSQL's per-value division scale
bytea_inbytea text input conversion ('\xDEADBEEF'::bytea as four bytes, not ten)
configYAML configuration loading
errorError types, SQLSTATE mapping, message sanitization, and error codes carried across the Ballista scheduler boundary
float_divPostgreSQL floating-point division: 22012 for a zero divisor where IEEE 754 answers an infinity
json_aggjson_agg and jsonb_agg, including their ORDER BY form
json_pgjson / jsonb input conversion and the ->, ->>, #>, #>> accessors
not_inPostgreSQL three-valued NOT IN over a candidate list
nth_valuenth_value, which rejects an offset of zero instead of answering NULL
ntilentile, typed integer rather than DataFusion's UInt64
pg_datetimeDatetime family: age, make_timestamp, make_interval, isfinite, justify_*, clock_timestamp, timeofday
pg_formatString-building family: format(), quote_literal(), quote_nullable()
pg_format_typeformat_type(oid, typemod) with the argument spellings PostgreSQL accepts
pg_typeofpg_typeof() and the Arrow → PostgreSQL type-name table it needs
pg_udfpg_catalog scalar functions beyond what datafusion-pg-catalog registers
protoProtobuf-generated gRPC types, compiled from proto/vairedb/v1/ by build.rs
scan_planCross-node scan-plan payload
stats_udafVariance and standard deviation family, exact over an exact input
udafOrdered-set aggregates percentile_cont and percentile_disc
uuid_inuuid input conversion, accepting PostgreSQL's alternative spellings
within_groupRemaining WITHIN GROUP aggregates: mode() and the hypothetical-set family

Protobuf Definitions

Service definitions live in proto/vairedb/v1/:

  • node_service.proto -- Register, Heartbeat (bidirectional stream), ReportFailure
  • write_service.proto -- ExecuteWrite (DML dispatch to core nodes)
  • catalog.proto -- Metadata messages (TableMeta, ColumnDef, ShardMeta, NodeMeta, AnonymizationSecret)
  • error.proto -- Shared VdbErrorCode enum (query, storage, cluster, catalog, internal codes)

Code is generated automatically by vairedb-common/build.rs during cargo build.

License

Apache License 2.0 -- see LICENSE

Contributors

matteobovetti

50 commits

dependabot[bot]

17 commits

matteobovetti/vairedb

VaireDB is a cloud native, high performance distributed analytical database.

Rust

14

68 commits

updated Sep 21, 2026

See the code

See what people are saying (2)

SourceMessageScoreDate

VaireDB, I'm looking for Rust OSS contributors (r/rust)

Hello! I started this hobby projects some months ago, VaireDB is a analytical database that aim to scale DuckDB using Data Fusion as a distributed query engine. On top we have PostgreSQL wire protocol, so any PGSQL clients can interact with VaireDB. The project is starting growing a lot in term of…

0

Sep 22, 2026

VarieDB, a cloud native, high performance distributed analytical database. (r/rust)

I would like to share a personal project (first made with Rust), where I have tried to scale DuckDB as a shard level core node, with Data Fusion and PostgreSQL wire protocol on top. [https://github.com/matteobovetti/vairedb](https://github.com/matteobovetti/vairedb) Note: It's a personal project…

0

Sep 22, 2026

README

VaireDB

VaireDB is a cloud native, distributed SQL database that combines PostgreSQL wire compatibility, with DuckDB's columnar vectorized execution engine for high-throughput analytical workloads across a horizontally scalable cluster.

Read the When use VaireDB section for understanding where VaireDB is best suited for your use cases.

[!IMPORTANT]
VaireDB is currently under active development. Breaking changes may occur and major features may be added. Consider this a work in progress and not yet ready for production use. Any contributions are welcome for targeting the production-ready v1.0 release.

Overview

VaireDB exposes a unified SQL interface through the PostgreSQL wire protocol (v3), allowing connections from any standard PostgreSQL client (psql, JDBC, etc.). Under the hood, data is hash-sharded across core nodes, each running an embedded DuckDB instance optimized for OLAP queries.

Key characteristics:

  • PostgreSQL-compatible SQL via DataFusion parser with automatic dialect translation to DuckDB.
  • Horizontal scalability through hash sharding across core nodes (range sharding planned).
  • Analytical performance powered by DuckDB's columnar vectorized engine.
  • Fault tolerance with configurable replication factor and quorum-based writes.
  • Column pseudonymization for compliance: declared columns are HMAC-SHA256 hashed in the coordinator so plaintext never reaches storage.
  • Operational simplicity as self-contained Rust binaries with YAML configuration.

When use VaireDB

Use Cases

  • CQRS read side — an analytical database positioned close to microservices' transactional databases, serving the query (read) side of a CQRS architecture. Transactional systems keep handling writes in their own stores, while VaireDB absorbs the heavy read and aggregation traffic that would otherwise contend with operational workloads — keeping write paths fast and read paths scalable.

  • Shared read model — a denormalized, read-optimized view of data shared across a microservices ecosystem. Instead of each service repeatedly joining and reshaping data from many sources, VaireDB holds a consolidated, query-friendly representation that teams can reuse, reducing duplicated effort and keeping cross-service reporting consistent.

  • Data fabric or micro-fabric — deployable both as a wide data fabric spanning the whole ecosystem and as a micro-fabric local to each bounded context. The same engine scales from a single bounded context to an organization-wide layer, so you can start small within one domain and grow toward a shared analytical backbone without changing technology.

  • Compliance datastore — supporting data take-out (export), deletion, and anonymization. By centralizing a queryable copy of data, VaireDB makes it easier to satisfy regulatory obligations such as subject-access exports, right-to-be-forgotten deletions, and anonymization, without hunting through every individual service store.

Architecture

VaireDB follows a coordinator/worker topology:

┌──────────────────────────────────────────────────┐
│                   Clients                         │
│            (psql, JDBC, any PG driver)           │
└──────────────────────┬───────────────────────────┘
                       │ PostgreSQL wire protocol (port 5432)
                       ▼
┌──────────────────────────────────────────────────┐
│               Coordinator Node                    │
│  ┌─────────┐ ┌────────┐ ┌──────────────────┐    │
│  │ Catalog │ │ Router │ │ Ballista Sched.  │    │
│  └─────────┘ └────────┘ └──────────────────┘    │
└──────┬───────────────┬───────────────────────────┘
       │ gRPC writes   │ reads (Ballista)
       ▼               ▼
┌────────────┐  ┌────────────┐  ┌────────────┐
│ Core Node  │  │ Core Node  │  │ Core Node  │
│  (DuckDB)  │  │  (DuckDB)  │  │  (DuckDB)  │
└────────────┘  └────────────┘  └────────────┘
  • Coordinator handles client connections, SQL parsing, query planning, metadata management, and dispatching work to core nodes.
  • Core Nodes store data in DuckDB, execute shard-local queries, and replicate writes.

For full details, see the Architecture Documentation.

Project Documentation

VaireDB Documentation

System Design Documentation

All documentation lives under docs/, split into architecture references, feature designs, and testing notes.

Architecture (docs/specs/):

DocumentDescription
Architecture IndexTop-level index with references to all architecture sections
OverviewWhat VaireDB is and its high-level value proposition
Design GoalsGoals and non-goals for the current version
System ArchitectureHigh-level topology and node types
Core Node (DuckDB)Embedded DuckDB engine, storage, and query execution
Coordinator NodeQuery routing, distributed planning, and metadata catalog
Data DistributionSharding strategy and replication
Cluster CoordinationNode discovery, leader election, failure detection
Communication LayerProtocols, wire formats, client interface
Distributed Query ProcessingQuery lifecycle and optimization
Transactions and ConsistencyConsistency model and distributed transactions
Fault Tolerance and RecoveryWAL, snapshotting, node recovery, quorum
SQL Compatibility StatusThe per-axis status of PostgreSQL compatibility, summarized from the gap census
SQL Gap AnalysisWhat a PostgreSQL client cannot fully do against VaireDB today
RoadmapRoadmap for next releases
GlossaryTerm definitions
LinksExternal references

Features (docs/features/):

DocumentDescription
ComplianceData pseudonymization, take-out, and deletion for regulated environments

Getting Started

Prerequisites

  • Rust 1.95 or later (2024 edition)
  • Protobuf compiler (protoc) for gRPC code generation
  • Make for build automation

Building

# Debug build
make build

# Release build
make build-release

# Type-check only (faster feedback loop)
make check

Running Locally - Binary

Start the coordinator:

make run-coordinator

In a separate terminal, start a core node:

make run-core

Connect with any PostgreSQL client:

psql -h localhost -p 5432

Running Locally - Docker Compose

Start a small VaireDB cluster (1 coordinator + 5 core node):

make e2e-up

Stop the small VaireDB cluster:

make e2e-down

Configuration

Configuration uses YAML files with environment-based overlays:

config/
├── coordinator/
│   └── config.yml   # Default coordinator configurations
└── core/
    └── config.yml   # Default core configurations

Default ports:

PortService
5432PostgreSQL wire protocol (client connections)
50040Coordinator gRPC (node registration, heartbeats)
50041Core node gRPC (write dispatch)
50050Ballista scheduler (distributed query execution)

Contributing

Project Layout

vairedb/
├── config/                    # YAML configuration files
├── crates/
│   ├── vairedb-coordinator/   # Coordinator node binary
│   ├── vairedb-core/          # Core node binary
│   └── vairedb-common/        # Shared protobuf code, config, scan plans
├── docker/                    # Dockers file
├── docs/                      # Architecture and testing documentation
├── proto/vairedb/v1/          # Protobuf service definitions
├── tests/e2e/                 # E2E tests
└── Makefile                   # Build automation

Development Workflow

# Format code
make fmt

# Run linter (clippy, fails on warnings)
make lint

# Run all tests
make test

# Run tests for a single crate
cargo test --package vairedb-coordinator

# Run a specific test
cargo test --package vairedb-coordinator -- test_name

# Run E2E tests
make e2e

# Generate code coverage
make coverage

Key Modules

Coordinator (crates/vairedb-coordinator/src/):

ModuleResponsibility
anonymizationColumn pseudonymization: HMAC-SHA256 hashing and in-statement rewriting of declared columns before writes leave the coordinator
catalogPersistent metadata catalog (tables, shards, nodes, anonymization secrets) exposed as a store and as queryable virtual tables
channel_poolConnection pool for gRPC channels to core nodes
column_typesRead-path mapping from a catalog-declared column type to the Arrow type (and PostgreSQL OID) the coordinator advertises for it
configYAML configuration loading
errorCoordinator error types and their mapping to wire error codes
node_servicegRPC NodeService (register/heartbeat/report) and the heartbeat-based failure detector
pgwire_handlerPostgreSQL wire-protocol handler: the single SQL parse and read-path AST rewrites, statement classification and table-name extraction, query routing, DDL/DML execution, result encoding, and catalog introspection
replicationQuorum writes plus a background retry/backoff loop that tails missed writes to lagging replicas
schedulerEmbedded Ballista scheduler: distributed read planning, plan codecs, and shard-affinity task distribution
write_routerResolves shards and dispatches writes to core nodes
write_sql_clWrite-path-only compatibility layer: PostgreSQL-dialect rewriting to DuckDB-compatible form plus shard-routing decisions
utilCross-cutting helpers (epoch timestamps, shard-local table naming)

Core Node (crates/vairedb-core/src/):

ModuleResponsibility
ballista_execBallista executor for distributed SELECT
configYAML configuration loading
engineDuckDB instance management
errorCore node error types
heartbeatRegistration and periodic heartbeats to coordinator
table_providerCustom DataFusion ExecutionPlan that runs shard-local SQL against DuckDB shards
write_queueBounded channel serializing writes to DuckDB
write_servicegRPC service receiving DML from coordinator, with dedup cache and param conversion

Shared (crates/vairedb-common/src/):

Code that must be identical on both sides of the wire. A distributed stage crosses the wire naming its functions, and the executor resolves those names in its own registry, so every function whose PostgreSQL semantics differ from the engine default is implemented once here and registered on every node that plans or executes a read.

ModuleResponsibility
avg_udafPostgreSQL-exact avg over integer columns: numeric at PostgreSQL's per-value division scale
bytea_inbytea text input conversion ('\xDEADBEEF'::bytea as four bytes, not ten)
configYAML configuration loading
errorError types, SQLSTATE mapping, message sanitization, and error codes carried across the Ballista scheduler boundary
float_divPostgreSQL floating-point division: 22012 for a zero divisor where IEEE 754 answers an infinity
json_aggjson_agg and jsonb_agg, including their ORDER BY form
json_pgjson / jsonb input conversion and the ->, ->>, #>, #>> accessors
not_inPostgreSQL three-valued NOT IN over a candidate list
nth_valuenth_value, which rejects an offset of zero instead of answering NULL
ntilentile, typed integer rather than DataFusion's UInt64
pg_datetimeDatetime family: age, make_timestamp, make_interval, isfinite, justify_*, clock_timestamp, timeofday
pg_formatString-building family: format(), quote_literal(), quote_nullable()
pg_format_typeformat_type(oid, typemod) with the argument spellings PostgreSQL accepts
pg_typeofpg_typeof() and the Arrow → PostgreSQL type-name table it needs
pg_udfpg_catalog scalar functions beyond what datafusion-pg-catalog registers
protoProtobuf-generated gRPC types, compiled from proto/vairedb/v1/ by build.rs
scan_planCross-node scan-plan payload
stats_udafVariance and standard deviation family, exact over an exact input
udafOrdered-set aggregates percentile_cont and percentile_disc
uuid_inuuid input conversion, accepting PostgreSQL's alternative spellings
within_groupRemaining WITHIN GROUP aggregates: mode() and the hypothetical-set family

Protobuf Definitions

Service definitions live in proto/vairedb/v1/:

  • node_service.proto -- Register, Heartbeat (bidirectional stream), ReportFailure
  • write_service.proto -- ExecuteWrite (DML dispatch to core nodes)
  • catalog.proto -- Metadata messages (TableMeta, ColumnDef, ShardMeta, NodeMeta, AnonymizationSecret)
  • error.proto -- Shared VdbErrorCode enum (query, storage, cluster, catalog, internal codes)

Code is generated automatically by vairedb-common/build.rs during cargo build.

License

Apache License 2.0 -- see LICENSE

Contributors

matteobovetti

50 commits

dependabot[bot]

17 commits

Languages

Rust

99.9%