Skip to content

ADR-0005: One logical database + role per service

Synced read-only from /home/synnet/synvirt-platform/docs-internal/adr/0005-per-service-logical-databases.md. Edit at the source, not here.

ADR-0005: One logical database + role per service

Section titled “ADR-0005: One logical database + role per service”
  • Status: Accepted
  • Date: 2026-06-28

We start on one PostgreSQL instance but must be able to split data across hosts later without rewriting apps.

Run a single Postgres now, but with separate databases and owner roles per service: portal, payload, keycloak, discourse. Each app connects via its own connection string (DATABASE_URL, PAYLOAD_DATABASE_URI, etc.). The infra/postgres/init/01-databases.sh bootstrap creates each DB owned by its role and (PG15+ correctness) hands the public schema to that role.

  • Moving a service’s data to its own Postgres/host later = pg_dump/restore that one database and change its connection string. No code change, no shared-schema entanglement.
  • Migrations are owned per service (sqlx for portal; Payload manages its own schema; Keycloak imports its realm).
  • Slightly more credentials to manage — handled via SOPS (ADR references the secrets layout in infra/secrets/).