We recommend Option B: migrate the primary application database from our self-managed Postgres cluster to a managed Postgres provider by end of Q2. This trades roughly $4k/month in additional infrastructure spend for the elimination of an entire on-call rotation and a measurable improvement in recovery-time objective.
TL;DR
Context
Our primary application database — a self-managed Postgres 14 cluster running on three EC2 instances behind pgbouncer — has been the source of three of the last six P1 incidents this year.1 Each incident has triggered a multi-hour war room, and the patterns are consistent: routine maintenance work that is well-trodden territory for a managed provider becomes an evening of paging on-call engineers for us.
The infrastructure team has quietly absorbed this work since the cluster was first stood up in 2022. Two of the three engineers familiar with its operational quirks are leaving the team in Q3, which forces the question now rather than later.
We've kept self-managed Postgres for two reasons: cost, and a historical concern about query performance under managed offerings. Recent benchmarking against aws-rds and a leading third-party provider suggests neither concern still holds at our scale.
Options
We considered three viable paths. A fourth — rewriting hot paths to remove pressure from the database — was discussed and parked; it does not address the operational risk on a useful timeline.
Stay self-managed, hire to fill the gap
Backfill the two departing engineers with infra hires explicitly chartered to operate Postgres. Continue running the existing cluster.
Pros
- No migration risk or change-window required
- Lowest direct infrastructure cost ($0 net new)
- Preserves full configuration control
Cons
- Hiring lead time is 4–6 months in current market
- Operational risk window remains open through Q3/Q4
- Loaded cost of two senior infra hires exceeds the managed delta
Migrate to a managed Postgres provider
Move the primary cluster onto a managed offering with point-in-time recovery, automated minor-version upgrades, and 24/7 vendor on-call.
Pros
- Eliminates the in-house Postgres on-call rotation
- RTO improves from ~90 min to ~15 min on advertised SLAs
- Vendor handles minor-version patching and PITR
Cons
- ~$4k/month net new spend at current load
- One scheduled migration cutover required
- Reduces low-level configuration flexibility
Adopt a serverless Postgres-compatible store
Migrate to a newer serverless Postgres-compatible service. Ambitious; would also reduce infrastructure spend over time.
Pros
- Lowest steady-state cost at our access pattern
- Auto-scales without manual capacity planning
- Modern developer ergonomics
Cons
- Subset of Postgres extensions supported
- Newer vendor — fewer reference customers at our scale
- Migration is more invasive; touches application code
Recommendation
Option B clears the operational risk on the timeline that matters and does so without rewriting application code. The $4k/month delta is real, but it is an order of magnitude less than the loaded cost of two infra hires we'd need under Option A — and it buys us back the time of the engineers we still have.2
Option C is appealing in the long run, but the migration scope is larger than the operational problem we are trying to solve, and the vendor risk profile is not yet what we want underneath the primary database. We will revisit Option C in 12 months, by which time both the vendor and our own internal abstractions will have moved.
Risks & Mitigations
| Risk | Likelihood | Mitigation |
|---|---|---|
| Cutover window exceeds estimated 30 minutes, causing a customer-visible outage | Medium | Two full dress rehearsals against a clone; cutover in a Saturday low-traffic window with rollback plan validated end-to-end. |
| Managed provider's extension support gaps surface late in migration | Low | Audit production extension usage in week one; raise a vendor ticket on any non-standard extensions before committing to a cutover date. |
| Cost grows beyond the $4k/month delta as load increases through the year | Medium | Set a billing alarm at 1.5× projected spend; quarterly right-sizing review with the vendor account team. |
Decision Required
- Deadline
- 2026-05-23 — to keep cutover on the Q2 path
- Approvers
- Priya Natarajan (VP Engineering), Daniel Okafor (Head of Infrastructure)
Appendices
Appendix A — Cost analysis
Three-year total cost of ownership comparison, fully loaded, at current production load.
| Line item | Self-managed | Managed |
|---|---|---|
| Compute & storage | $2,100/mo | $5,800/mo |
| Backups & PITR | $400/mo | included |
| On-call labour (loaded) | $3,200/mo | $300/mo |
| Total | $5,700/mo | $6,100/mo |
Appendix B — Migration timeline
- Week 1–2: Provision target instance; replicate schema; audit extension usage.
- Week 3–4: Set up logical replication from primary; backfill historical data.
- Week 5: First dress rehearsal against clone; capture metrics.
- Week 6: Application changes for connection-string rotation behind a feature flag.
- Week 7: Second dress rehearsal; sign-off from infra and platform leads.
- Week 8: Production cutover during scheduled Saturday window; 48-hour observation period.
Appendix C — Prior discussion notes
The question of moving off self-managed Postgres has been raised twice before — in the 2023-Q4 architecture review and again in the 2024-09 reliability offsite. In both cases the team chose to defer, citing migration risk and an expectation that operational load would remain manageable.
"Defer migration; revisit in 12 months. Operational cost is currently absorbed by team capacity but this assumption deserves a fresh look as headcount changes." — 2024-09 reliability offsite minutes
Two factors have shifted since: (1) two of three Postgres-fluent engineers leaving the team, and (2) managed-provider pricing improvements that close most of the historical cost gap.