Implementation lesson · HerpSync
Routing HerpSync Custom Domains Without Querying the Database
Domain resolution sits on the request hot path. The routing layer needs a small, fast host-to-tenant answer, but normal application database access is a poor fit for the edge environment where that routing decision occurs.
- EVC role
- Designed and built end to end
- Product status
- Soft launch
- Period
- Development began in June 2026
Context
HerpSync is a multi-tenant SaaS product for animal breeders. It serves public tenant pages through platform subdomains and customer-controlled domains, so the incoming host must resolve to the correct tenant before the application handles the page request.
EVC Studios designed and built HerpSync end to end.
Constraints
- Resolve platform and custom hosts before application rendering
- Keep the primary application database authoritative
- Avoid placing private tenant or operational data in the routing projection
- Accept and manage bounded eventual consistency
- Make synchronization failures observable and repairable
Decision
The architecture keeps domain ownership and activation state in the application database, then synchronizes only the routing key and tenant slug into an edge-readable configuration projection. Request routing reads the projection; application workflows and domain management continue to use authoritative database state.
Architecture and workflow
The sequence below is both the visual flow and its text description.
- Step 1
Normalize host
Remove routing-irrelevant variation and distinguish platform hosts from custom hosts.
- Step 2
Read projection
Resolve a custom host to the minimum tenant-routing identifier at the edge.
- Step 3
Rewrite request
Send the request to the tenant-aware public route without querying the primary database.
- Step 4
Reconcile state
Synchronize approved domain changes and periodically repair projection drift.
Authoritative state and read-optimized projection
The application database remains the source of truth for domain ownership, verification, activation, and tenant relationships. The edge projection answers one narrower question: which tenant route should handle this normalized host?
Keeping those responsibilities separate prevents the routing layer from becoming a second business database. The projection contains only what the hot path needs and can be rebuilt from authoritative state.
Synchronization, invalidation, and eventual consistency
A domain change is not complete merely because one system accepted it. Activation coordinates authoritative state with the routing projection, while removal or reassignment invalidates the old mapping.
The projection is eventually consistent, so implementation needs explicit intermediate states and conservative failure behavior. An unresolved or stale host should not silently route to an unrelated tenant.
- Write domain decisions to authoritative state
- Project only activated routing records
- Remove obsolete mappings deliberately
- Reconcile periodically instead of trusting one update
Failure behavior and operational visibility
Projection updates can fail independently from application writes. Operations therefore need visibility into pending, failed, and inconsistent mappings, plus a repeatable reconciliation path.
Logs and status views should identify the domain record and synchronization stage without exposing private tenant data. A safe fallback may show an unconfigured-domain response while preserving the requested host for diagnosis.
An implementation correction exposed a vendor constraint
During implementation, the projection provider rejected a key format that appeared natural for hostnames. Correcting the encoding reinforced a broader lesson: provider configuration stores have naming and consistency rules that belong in the adapter boundary, not scattered through domain workflows.
The correction was technical, not evidence that one provider is universally preferable. A different edge platform could use a different read-optimized store while retaining the same source-of-truth boundary.
Cost and maintenance consequences
The pattern removes a database dependency from the routing hot path, but it adds synchronization code, reconciliation, operational states, provider configuration, and another failure boundary. Those costs are justified only when custom-domain routing is a real product requirement.
A smaller product using one canonical host or simple platform subdomains can often resolve routing without a synchronized projection.
Trade-offs
- Fast edge reads in exchange for a second, eventually consistent projection
- Simple routing records in exchange for synchronization and reconciliation work
- Provider-specific adapter constraints in exchange for avoiding database access on the hot path
Context-specific limitations
- This design is specific to a multi-tenant product with custom domains.
- A second projection creates synchronization responsibilities.
- Products without custom domains usually do not need this boundary.
- The lesson is not a universal endorsement of Edge Config or any provider.
Generalizable lessons
- Keep business truth in one authoritative store.
- Project only the minimum data required by the read path.
- Design reconciliation when introducing a projection, not after drift appears.
- Treat provider naming and consistency rules as adapter concerns.
- Define safe behavior for missing and stale mappings.
Decision checklist
- Does routing occur before normal application database access?
- What is the authoritative domain state?
- What minimum fields belong in the projection?
- How are activation, removal, and reassignment synchronized?
- What happens during propagation delay or failure?
- How can operators detect and reconcile drift?