Database providers
Seven first-class database families. One product entity model. Switch providers without changing product logic.
Vadyl ships first-class providers across seven storage families. Your product entity model is the same regardless of which one you bind to a project. The capability surface compiler resolves canonical operations through the chosen provider, executing natively where the provider supports the operation and supplementing at runtime where it does not.
The seven storage families
- Relational — PostgreSQL, MySQL, SQL Server
- Document — MongoDB
- Key-Value — Redis
- Graph — Neo4j
- Wide-Column — Cassandra
- Time-Series — TimescaleDB, MongoDB time-series collections
- Vector — pgvector, Pinecone, Weaviate
Maturity tiers
Each provider declares a ProviderMaturityTier that gates whether it can serve traffic in a given environment:
- CoreProduction — production-ready, no caveats. PostgreSQL, MongoDB, MySQL, Redis.
- ProductionWithConstraints — production-ready with explicit caveats (e.g. specific isolation levels not supported). SQL Server, Neo4j.
- Preview — opt-in only. Cassandra, time-series, vector.
- Experimental — local dev only.
Operators set the required maturity per environment via Vadyl:RequiredMaturityTier; bindings to lower-tier providers fail closed at startup.
Capability matrix
Each provider declares its DbCapabilities across 27 categories — DML, query, join, pagination, types, text, identity, indexing, constraints, DDL, schema objects, transactions, aggregation, functions, predicates, value generation, namespace, security, cryptography, change tracking, storage model, document ops, key-value ops, graph ops, consistency, schema transitions, and database sources.
Vadyl's read coordinator and write coordinator branch on capabilities — never on provider name strings — so adding a new provider doesn't require changing any product logic or canonical pipeline.
Bind a provider
// vadyl.config.ts
bindings: {
primary: {
type: "postgres",
url: process.env.DATABASE_URL,
pool: { min: 2, max: 20 },
},
analytics: {
type: "postgres",
url: process.env.ANALYTICS_DATABASE_URL,
role: "readReplica",
},
cache: {
type: "redis",
url: process.env.REDIS_URL,
},
},Native vs hybrid execution
Take a query like WHERE status IN ('paid', 'fulfilled') AND total > 100 ORDER BY createdAt DESC LIMIT 50. On PostgreSQL or MySQL, the entire query compiles to a single SQL statement that the database executes natively. On a key-value substrate, Vadyl runs the index lookup natively, fans out the row reads, and applies the filter / sort / limit at the application boundary — same canonical result, different execution shape.
Cross-provider operations
When a single operation spans multiple providers (read from Postgres, then update Redis), Vadyl uses the cross-provider planner to build a typed DAG and execute steps in topological order with compensating actions registered for rollback. Atomicity is provided by saga compensation — never by a distributed transaction Vadyl can't guarantee.
Switch providers
Changing from MongoDB to PostgreSQL is a binding change in vadyl.config.ts plus a deploy. The schema-transition pipeline classifies the migration, generates the right DDL for the target, runs backfill if needed, and switches the project atomically. Product logic does not change.
See also
- Capability surfaces — the contract layer underneath every provider.
- Capability matrix reference — full per-provider capabilities.
- AST reference — the canonical operation language providers compile against.