Transitioning 4,500 users, turning off legacy infrastructure, and controlling cloud cost creep — go-live was never the finish line for me. Adoption was.
Change management
I never treated this as end-of-project training bolted onto the schedule. It started at mobilization and ran the whole length of the program, because ~4,500 people had to trust the new numbers, not just get handed a login.
"We'll train people before go-live" isn't a plan, it's a hope. Staging awareness, involvement, training, and adoption as distinct tracked stages is what let me catch that Sales was behind on champion recruitment two months out, not two weeks out.
| Stage | When | What I ran | Measured by |
|---|---|---|---|
| Awareness | Mobilize | Comms on the why; impact broken out by function | Reach |
| Involvement | Design → UAT | SMEs pulled into mapping and parity sign-off; champions recruited per function | SME participation |
| Training | Pre-cutover | Role-based training; office hours; quick-reference guides | Completion % |
| Adoption | Post go-live | Champions support; usage nudges; feedback loop | Active users vs. target |
I recruited a champions network inside every function, one per business unit, and tracked usage against a target instead of assuming adoption would just happen because the platform was live.
Retire the old, own the cost
I didn't switch off the SQL Server EDW on a date from the plan — I switched it off against criteria I set. A defined confidence window, adoption holding, and zero reconciliation gaps, before I signed off.
| Criterion | Status |
|---|---|
| Confidence window elapsed with no reconciliation gaps | Met |
| Adoption steady above target | Met |
| No dependency still reading legacy | Met |
| Archive & retention captured for compliance | Met |
| Dimension | Baseline | Actual | Result |
|---|---|---|---|
| Scope | 250 reports, 8 functions | 250 delivered | Met |
| Schedule | ~9 months | +2 weeks (Wave 3 SME slip) | Within tolerance |
| Budget | Approved baseline | On budget | Met |
| Financial parity | Zero-defect reconciliation | Zero variance at go-live | Met |
| Benefit | Legacy retired; TCO reduced | Decommissioned; scope cut 38% via my rationalization | Realized |
Scar tissue
What I Actually Decided Here
Decision: Post-cutover, I found power users running unoptimized legacy-style SQL that was causing cost spikes. I set auto-suspend timeouts on the virtual warehouses and enforced a mandatory 15-minute optimization check for anyone running heavy queries.
Friction: Analysts complained about queries getting cut off during initial testing — cloud-native query discipline wasn't a habit yet, and it showed.
Outcome: I saved $50K in compute overruns in the first month alone, and it shifted the company's query culture toward cloud-native habits instead of just tolerating the old bad ones on a new bill.
What I'd tell the next TPM
A program that closes without a written retro just repeats its mistakes on the next one, with a different TPM re-learning them the hard way. Writing down the SME-booking miss is what makes it a lesson instead of a grudge.
Rationalizing first cut 38% of scope before I let anyone write a line of code. Daily dual-run reconciliation meant cutover held no surprises. Naming a business owner per field turned definition fights into decisions I could point back to.
I didn't book SME time far enough ahead — the one schedule slip I took traced straight back to it. Action for next time: reserve SME capacity per wave at planning, not at UAT.
Golden thread · closed
The close-amount field that surfaced a 6% variance in test became my proof point for the whole program: the reconciliation strategy did its job, the definition got fixed by the business, and go-live reconciled to the penny. The whole migration, in one field.