Michael Paycer — SQL Server migration
SQL Server Guide

SQL Server Migration and Upgrade Playbook

Most SQL Server migrations fail on the details, not the big decisions. This is the repeatable playbook I use to move databases with minimal downtime and no surprises.

Most SQL Server migrations don't fail on the big decision. They fail on a forgotten login, a job that didn't come across, a linked server nobody documented, or a query that ran fine on the old box and fell off a cliff on the new one. The big choices are easy to reason about; the details are what bite.

This is the repeatable playbook I run, whether it's a version upgrade (say SQL Server 2016 to 2022) or a platform move to the cloud. The two overlap heavily — the same sequence works — but I'll flag where they diverge.

SQL Server migration sequence: assess, choose target, stage, cut over, validate, with a rollback path

Assessing the source environment

You can't migrate what you haven't inventoried. Before anything moves, capture:

Microsoft's free Data Migration Assistant (DMA) does the compatibility and feature-parity analysis for you: it flags breaking changes, behavior changes, and deprecated features for your target version. For a version jump, that report is your risk list.

Choosing the target: in-place, side-by-side, or cloud

Three shapes, in rough order of risk:

Compatibility level and the cardinality estimator

Here's the upgrade detail that generates the most "it got slower after we moved" tickets: the cardinality estimator (CE).

SQL Server got a new CE in 2014, and it changes how the optimizer estimates row counts — usually for the better, sometimes dramatically worse for a specific query. The safe pattern is to upgrade the engine but keep the old database compatibility level, get stable, then raise the compat level deliberately and watch for regressions.

If a raise causes trouble, you have graceful escape hatches instead of an emergency: the LEGACY_CARDINALITY_ESTIMATION database-scoped option, and Query Store to catch and, if needed, force the old plan while you fix the query properly (parameter sniffing and bad plans).

Migration methods

Match the method to size and downtime tolerance:

Method Best for Downtime
Backup / restore Most databases Length of final restore
Detach / attach Same-server moves Short
Log shipping Large DBs, tight windows Minimal (final log only)
AG seeding Already on Always On Minimal
Azure Database Migration Service (assessed with DMA) Cloud targets Online (MI / SQL VM) or offline

For anything large where downtime is precious, log shipping (or AG-based seeding) lets you pre-stage the data and cut over with only a final log restore.

The cutover plan

The migration is the easy part; the cutover is where the forgotten details live. Pre-cutover checklist:

Then: freeze writes, take the final log backup and restore it, flip connectivity, and run a smoke test before you tell anyone it's done.

Rollback: your safety net

Define the rollback trigger and time-box it before cutover — "if the smoke test isn't green by X, we roll back" — so nobody's improvising under pressure. Keep the old instance intact and reachable, and drive the switch with a DNS name or SQL alias rather than hard-coded server names; that makes rollback a single flip instead of a redeploy. The side-by-side approach earns its keep here.

Post-migration validation

Cutover isn't done until it's verified:

A migration run this way is boring, which is the goal. If you'd rather have it planned, staged, and cut over with a real rollback path, that's exactly the kind of engagement I take — see SQL Server migration services, review client results, or get in touch.


References