Default to PostgreSQL for new stateful services
- Status: proposed
- Deciders: <team or role>
- Technical story: <issue link> · Date: <YYYY-MM-DD>
Context and Problem Statement
We operate two supported relational engines with duplicated operational cost. New services pick databases ad hoc, which fragments runbooks, onboarding, and on-call. We need a default that matches where we already have depth (PostgreSQL) without forcing unowned migrations from MySQL.
Decision Drivers
- Reduce duplicated SRE and platform surface
- One obvious default in templates and sample repos
- Honest exceptions where legacy or certification blocks PostgreSQL
Considered Options
- Status quo (split defaults) — lowest migration risk; highest long-term toil and unclear ownership of “which engine here”.
- Force PostgreSQL everywhere — rejected: would drive unowned migrations and break vendor-certified MySQL workloads.
Decision Outcome
Chose PostgreSQL 15+ as the default for new stateful services after 2026-05-01, with an explicit, reviewed opt-out path. Existing MySQL services stay until an owned migration is proposed.
Consequences
- Greenfield work converges on one engine for provisioning, testing, and docs
- Opt-out ADRs and vendor exceptions remain first-class, not a hack
- MySQL expertise remains needed for a long tail of services
Pros and Cons of the Options (summary)
PostgreSQL default wins on operability and existing team skill in-house. MySQL is still valid where constraints are real; the cost is ongoing dual support until legacy shrinks.
Confirmation
Platform council + SRE; recorded in this ADR and linked from internal templates.