ADR-008: Separate Databases Per Product
Date: 2026-07-07
Status: Accepted
Deciders: Pete Carroll
Context
As Traxs Group expands from RoundTrip to Waypoint and Relay, a fundamental architectural decision must be made: do all three products share a single database, or does each product get its own database?
This decision affects schema evolution, deployment independence, team scalability, data isolation, and the integration story between products.
Decision
Each Traxs product gets its own dedicated Azure SQL database. Products share data through the Command Center API, not through direct database access.
RoundTrip → sqldb-roundtrip-production
Waypoint → sqldb-waypoint-production
Relay → sqldb-relay-production
Cross-product data sharing uses the Command Center API as the integration layer:
Waypoint needs RoundTrip revenue data:
Waypoint API → Command Center API → RoundTrip API → returns DTO
(never direct database access)
Alternatives Considered
Option A — Shared Database, Shared Schema
All three products read and write to the same Azure SQL database. Tables are prefixed or namespaced by product.
Rejected because:
- A migration in RoundTrip can break Waypoint and Relay — no deployment independence
- Schema changes require coordination across all product teams
- A single database becomes a scaling bottleneck as all three products grow
- Cannot sell, spin off, or deprecate a single product independently
- A bug that corrupts RoundTrip data could affect Waypoint and Relay data
Option B — Shared Database, Separate Schemas
One database server, separate schemas per product (roundtrip.*, waypoint.*, relay.*).
Rejected because:
- Still a single point of failure — if the database goes down, all three products go down
- Schema separation is a convention, not enforced isolation
- Migrations still risk cross-schema interference
- Harder to give each product independent backup/restore policies
Option C — Separate Databases (selected)
Each product has its own database. Cross-product data sharing via API.
Selected because:
- True deployment independence — RoundTrip migrations never affect Waypoint
- Products can scale their databases independently
- Clean product boundaries support future team structure (one team per product)
- Products can have independent backup, restore, and retention policies
- Integration through API is explicit, versioned, and auditable
Consequences
What becomes easier:
- Deploying RoundTrip schema changes without affecting other products
- Scaling each database independently based on actual product usage
- Onboarding developers to a single product without understanding the others
- Future team structure — dedicated developers per product work in independent codebases
- Selling or licensing individual products independently
What becomes harder:
- Cross-product queries require API calls rather than SQL joins
- Reporting that spans products (e.g. "total Traxs Group revenue across all products") must aggregate from multiple APIs
- Client record sync is eventual consistency, not immediate
- More Azure resources to manage and pay for
The integration pattern:
// Waypoint Executive Dashboard — Revenue Widget
// Does NOT query RoundTrip database directly
// Calls Command Center API which calls RoundTrip API
public async Task<RevenueSnapshot> GetRoundTripRevenueAsync(
Guid tenantId, CancellationToken ct)
{
var response = await _commandCenterClient
.GetAsync($"/v1/roundtrip/revenue-summary?tenantId={tenantId}", ct);
return await response.Content
.ReadFromJsonAsync<RevenueSnapshot>(ct);
}