Single Neon project with Postgres schema separation
One database for all Orvenath systems, separated by schema. Supabase rejected on free-tier pausing.
ADR-011 — Single Neon project with Postgres schema separation
Context#
The proposal engine was the first Orvenath system needing a database. Rather than provision databases per-system as they appear, a shared data layer was preferred — fewer connection strings, one dashboard, one backup surface, and a structure that future systems slot into rather than sit beside.
Supabase was the initial candidate, on the reasoning that one project could serve the whole company and reduce cost.
Cost turned out not to be the deciding factor. Both Neon and Supabase are free at current volume, so consolidation saved nothing. The decision had to rest on operational behaviour instead.
The disqualifying factor#
Supabase pauses free-tier projects after seven days of low activity, and paused projects do not resume automatically — someone must restore them manually from the dashboard.
Mapped onto this use case, that fails at the worst possible moment. A proposal is sent. The system sits idle for two weeks. The prospect opens the share link on day twelve — the single highest-value moment in the entire sales process — and receives an error page. The operator may not find out.
Neon also scales to zero, but wakes automatically on the next connection. A cold start, not a manual restore. For a system that is idle between sporadic client visits, that difference is decisive.
A keep-alive cron can work around the Supabase pause, but it introduces a silent-failure dependency guarding the most important client touchpoint.
Decision#
One Neon project, orvenath, with Postgres schemas separating concerns.
orvenath (database)
├── proposals.* clients, proposals, proposal_views, rate_limit_buckets
├── labs.* future product data
└── analytics.* future
Drizzle is configured with pgSchema("proposals") and schemaFilter: ["proposals"], so migrations from one system cannot touch another's tables. Future systems create their own schema in the same project.
Consequences#
- One connection string, one dashboard, one region decision
- Schema-level isolation; per-schema grants available later if anything needs it
- Neon branching enables running migrations on a branch before touching main
- Free-tier limits are now a shared resource across all future systems — watch as usage grows
- All systems share a failure domain; a Neon outage takes down everything at once
Revisit when#
A Labs product needs authentication with real end users, file storage, or realtime subscriptions. Supabase provides those natively and would earn its place — at which point the pausing constraint is also likely moot, since a product with users generates the activity that prevents it.