Implementation thesis
Phase 1 is the smallest useful outcome: every order write also lands in the new partitioned store, nothing reads from it, and one flag turns it off.
- Ships
- 17 Aug 2026, behind
orders_v2_shadow - Readers affected
- None. Every read stays on legacy.
- Undo
- Flag off in under a minute; nothing is lost.
The write bridge in orders-service copies each committed order to orders_p on pg16-orders within two seconds. That tests the new schema against real traffic – about 140,000 orders a day, peaking at 60 writes per second – before any customer-facing read depends on it.
The new store changes the row: monthly partitions on created_at, and amounts as integer minor units instead of numeric. Logical replication cannot carry that change, and orders-service already owns every write, so the bridge lives there, behind a flag.
Each later phase moves one kind of authority: history, then reads, then writes. Until the cutover in phase 4, every step reverses with a flag in under two minutes and pg11-main stays complete.
Scope boundary
In scope 5
- IN-1
public.ordersand its three indexes, moved toorders_p. - IN-2The write bridge in
orders-service, flagorders_v2_shadow. - IN-3
orders-backfilland itsbackfill_checkpointstable. - IN-4Cohort read routing in
orders-api, flagorders_v2_reads. - IN-5Drift, checksum and read-compare jobs; the
orders-crossingdashboard.
Out of scope 3
- OUT-1
order_lines,paymentsandrefunds. They follow on drawing M-15. - OUT-2API contract changes.
orders-apiv3 responses stay byte-identical. - OUT-3Shutting down
pg11-main. Other tables still live there.
Assumptions 4
- AS-1Peak writes stay under 90 per second. Today's peak is 60.
- AS-2
pg16-ordershas 1.9 TB free for a store of about 0.8 TB. - AS-3No schema change to
orderslands between v41 and G4. - AS-4The billing export can change its source once. See blocker Q1.
Non-goals 3
- NG-1Faster reads. The 180 ms target is today's 172 ms p95 plus margin.
- NG-2Removing the
orders_v2_*flags before G4. - NG-3Cleaning data. Rows keep their IDs, timestamps and values.
Execution map
Phases run in dependency order. No phase starts until the gate before it is signed, and a failed gate moves every date after it.
| Phase | Target surfaces | Expected outcome | Depends on | Validation signal | Gate |
|---|---|---|---|---|---|
| 01Shadow17 Aug 7 d min |
|
Every committed order is copied to orders_p within 2 s. Legacy stays authoritative; reads stay 100 % legacy. |
Schema v42 applied on pg16-orders. Flag deployed, off. Drift dashboard live. |
Hourly row-count drift under 0.01 %. Bridge errors under 0.1 %. Write p95 up by 5 ms at most. | G17 clean days |
| 02Backfill24 Aug 5 nights |
|
All rows older than the shadow start are copied in 280 batches of 50,000, 01:00–05:00 UTC. A failed batch resumes from its last checkpoint. | G1 signed. Replica lag alert on pg11-main set to 30 s. |
Row count and checksum per batch. Replica lag under 30 s in each window. No batch over 6 min. | G2116 / 116 checksums agree |
| 03Read shift31 Aug 6 d min |
|
Reads move to orders_p by customer cohort: 1 %, 10 %, 50 %, then 100 %. Writes stay dual; the legacy source stays available. |
G2 signed. Blocker Q1 answered. Mismatch alert live. | p95 under 180 ms at each step. Zero mismatches in read-compare. Error budget burn under 2 % a day. |
G324 h at 100 %, clean |
| 04Retire8 Sep 15 d min |
|
Writes freeze for up to 20 min while counts reconcile, then orders_p becomes authoritative. The bridge copies back to legacy for 14 days, then it is removed. |
G3 signed. Change window approved. Rollback RB-4 rehearsed in staging. | Reconcile diff of 0 rows before unfreeze. Reverse-bridge lag under 5 s. No rollback for 14 days. | G4Rollback window closed |
Gates
A gate is signed in the M-14 gate log, with the evidence attached. The signer is never the engineer who ran the phase.
-
G1 · Seven clean days
Seven consecutive days in which every hourly window shows row-count drift below 0.01 % and bridge errors below 0.1 %.
- Measured by
orders-drift-check: hourly counts bycreated_athour in both stores, onorders-crossing.- Signs
- Data platform lead
- On failure
- Fix the cause; the seven-day count restarts. If drift passes 0.1 %, run RB-1.
-
G2 · Checksums agree
For all 116 monthly partitions, January 2017 to August 2026, the row count and an ordered hash of
id, updated_at, amount_minormatch the source.- Measured by
partition-checksum, run after the last batch against a consistent snapshot ofpg11-main.- Signs
- Database reliability lead
- On failure
- Copy the failing partitions again from their checkpoints and re-run the check. Phase 3 waits.
-
G3 · Reads hold at 100 %
24 hours with all reads on
orders_p, p95 below 180 ms in every 5-minute window, and zero mismatches.- Measured by
orders-apilatency histogram, andread-compareon a 5 % sample checked against legacy.- Signs
- Orders service owner and SRE on-call
- On failure
- RB-3: return reads to the last clean step. Find the cause before stepping up again.
-
G4 · Rollback window closed
14 days since cutover with no rollback, reverse-bridge lag below 5 s throughout, and the month-end billing export reconciled.
- Measured by
- Bridge lag metric, the rollback log and the billing reconciliation report.
- Signs
- Director of platform engineering
- On failure
- After a rollback, the 14-day window restarts from the next cutover. The bridge stays.
Risk and rollback register
Each risk has a trigger that someone can see on the orders-crossing dashboard, and a fallback step from the rollback procedure in section 8.
| ID | Risk | Trigger | Mitigation | Owner | Fallback |
|---|---|---|---|---|---|
| RK-1 | The bridge slows checkout writes. | Write p95 in orders-service up 10 ms for 15 min. | Asynchronous bridge with a 10,000-item queue; overflow goes to the drift job for repair. | Orders service owner | RB-1, bridge off |
| RK-2 | Backfill starves pg11-main. | Replica lag over 30 s, or CPU over 70 %. | Batch size halves automatically; the window ends at 05:00 without exception. | Database reliability lead | RB-2, pause and resume next night |
| RK-3 | Amounts change in the numeric to minor-unit conversion. | Any mismatch on an amount field. | Property tests on 1 million sampled rows before phase 2 starts. | Data platform lead | RB-3, then copy the partition again |
| RK-4 | The billing export reads a half-moved source. | Export row count differs from the ledger. | Q1 must be answered before phase 3; the export stays pinned until then. | Billing systems lead | Keep the export on legacy until G4 |
| RK-5 | The cutover freeze runs long. | Reconcile diff is not 0 at minute 20. | Rehearse on a production-size copy in staging; the abort point is fixed at minute 20. | Incident commander | RB-4, authority stays legacy |
| RK-6 | A defect appears after the bridge is removed. | Defect reported after G4. | The 14-day window includes one month-end close, when most order corrections happen. | Director of platform engineering | Fix forward; point-in-time restore last |
Validation plan
Each check belongs to the phases it runs in. A check marked as gate evidence must be green in the gate log before the gate can be signed.
Runs through the phaseRuns once before the phase exitsGate evidence
| Check | Kind | 01 | 02 | 03 | 04 |
|---|---|---|---|---|---|
| Row-count drift, hourly | Automated | G1 | runs | runs | runs |
| Bridge errors and write p95 | Automated | runs | runs | runs | runs |
| Amount conversion property tests | Automated | once | |||
| Partition checksums, 116 | Data | G2 | once | ||
read-compare, 5 % sample | Automated | once | G3 | runs | |
Contract tests, orders-api v3 | Compatibility | runs | runs | ||
| Smoke: order history, refunds view, admin search | Manual | runs | once | ||
| Billing export against ledger | Data | runs | G4 | ||
| Cutover rehearsal in staging | Release | once | |||
| Reverse-bridge lag under 5 s | Automated | G4 |
Open questions and handoff
Blocker Q1Blocks phase 03
Does billing-export move to orders_p in phase 3, or stay on pg11-main until phase 4?
It reads orders through billing-export-ro, a logical replica of pg11-main. Once reads shift, that replica still works, but after cutover it only receives rows through the reverse bridge, and after G4 it receives nothing.
- Owner
- Billing systems lead
- Needed by
- G2 review, 31 Aug
- If unanswered
- Phase 3 does not start
Not blocking
- Q2Does the backfill need a pause on the last business night of the month?Can defer past phase 01
- Q3Is the cohort key for the read shift the customer ID or the account region?Can defer past phase 02
- Q4Do partitions before 2019 stay on primary storage or move to the cold tier?Can defer past phase 04
- Q5After G4, is
public.orderskept as a read-only archive or dropped after 90 days?Can defer past phase 04
Handoff
- Baseline
- Schema v41 at commit
a3f9e2c. Migration v42 is written and reviewed, not applied. - Flags now
orders_v2_shadowoff ·orders_v2_reads0 ·orders_authoritylegacy- Next action
- Apply v42 on
pg16-orders, then turn onorders_v2_shadowat 10:00 UTC on 17 Aug. - Evidence
- Gate log for M-14, one entry per gate, linked from
orders-crossing. - On-call
- Data platform rotation for phases 1 and 2; SRE on-call joins from phase 3.
Open the rollback gateRB-1 to RB-4
Any on-call engineer can run RB-1 to RB-3 without approval. RB-4 needs the incident commander. Every step leaves pg11-main complete until G4. After a rollback, the gate is reopened only when the failing signal has stayed clean for 24 hours.
| Step | When | Action | Effect | Time |
|---|---|---|---|---|
| RB-1 | Phase 01 | Turn off orders_v2_shadow. | Writes stop reaching orders_p within 30 s. Nothing is lost; the copy can be discarded. | < 1 min |
| RB-2 | Phase 02 | Pause orders-backfill. If drift passes 0.1 %, also run RB-1. | The last checkpoint is kept; the next window resumes from it. | < 2 min |
| RB-3 | Phase 03 | Set orders_v2_reads to the last clean step, or 0. | Writes are still dual, so legacy has every row. | < 2 min |
| RB-4 | Phase 04, before G4 | Freeze writes, confirm reverse-bridge lag is 0, set orders_authority to legacy, unfreeze, then set orders_v2_reads to 0. | Legacy is authoritative again with no lost writes. | ≤ 20 min frozen |
After G4 there is no flag rollback. Fix forward, or restore pg16-orders from its point-in-time backup.