MIGRATION · April 14, 2026 · 12 min read
SharePoint migration best practices: 2026 edition
SharePoint migrations fail the same way every year. Somebody moves the documents before the content types, everything lands in the wrong list schema, and the whole thing gets re-done over a weekend that nobody wanted to work. This post is the short version of what actually works, written in 2026 after a year of Graph-API-driven migrations became common practice and SPMT became the thing you reach for only when Graph genuinely cannot do the job.
The audience is IT leads running tenant-to-tenant, divestiture, or acquisition migrations on SharePoint Online. If you are on SharePoint 2016 on-prem, some of the sequencing still applies, but the tooling story is different.
Pre-migration audit
Every successful migration I have seen starts with an audit. Every failed one skipped it. The audit answers three questions:
- What is the site footprint? How many site collections? How many are active vs orphaned (no active users in 180 days)? How much content by size? Which sites host the top 20% of active documents? The answer to the last question shapes the cutover order.
- What is the permission sprawl? How many Anyone-with-the-link sharing links exist? How many external guests have access? Which sites have broken inheritance at item level (not just library level)? Broken inheritance at item level is almost always a pre-existing mess that you do not want to carry forward.
- What is the schema footprint? How many custom content types? How many custom site columns? How many list views are actually used (last access in 90 days) vs how many exist? You are going to migrate the schema, so you want to know how big it is.
Tools that enumerate this quickly: Microsoft 365 admin center reports for basic usage, MigrationFox’s free SharePoint & OneDrive oversharing assessment for permissions, and the Graph contentTypes endpoint for schema. Budget a day for the audit on a mid-size tenant. Budget a week if you have inherited the environment and have never looked at it.
Tenant-level prep
Do these things on the destination tenant before the first site migration:
- Publish sensitivity labels and DLP policies. If your destination tenant does not have labels published, any labelled content from the source lands as unlabelled. Publish first, migrate second.
- Set the default sharing policy. New and existing guests only, or Existing guests only, at the tenant level. Migrations inherit the destination tenant’s sharing capability — if your source had Anyone-links and your destination disallows them, the links will not be recreated. That is usually the intent, but you want it to be a deliberate choice.
- Raise relevant limits. The per-user API throttle on Graph is soft, not hard, but a large migration will hit 429s unless you are on a tenant with enough service-principal quota. Open a support ticket to raise app-context throttling before the weekend you planned to migrate, not on it.
- Provision destination users and groups. Every UPN in your mapping CSV needs to exist in the destination directory before permissions replay. If you are migrating fresh tenants, run AD Connect first (or an equivalent) so the principals resolve.
Sequencing: content types first, always
The single most common migration failure is “we moved the files and now all our columns are gone”. The fix is sequencing.
The order is:
- Site columns. Custom site columns are the leaf dependency for everything else. Enumerate them via Graph, recreate them on the destination site first.
- Content types. Content types depend on site columns. Create content types next, binding them to the columns you just created.
- Lists and libraries. Lists depend on content types. Create the list, attach the content type, and then start writing items into it.
- List items and files. With the schema in place, items get correct column values and files land with the correct content type binding.
- List views. After items exist, views can be evaluated. Create views last so the CAML filters reference real columns on a populated list.
- Pages and web parts. Pages reference lists and libraries. Migrate after item data exists.
- Permissions. Always last. Permissions reference everything, so fixing anything earlier in the sequence is cheaper if nothing is locked down yet.
If your tool does not enforce this sequence, enforce it yourself by running the migration in phases. MigrationFox’s Full Site Migration enforces it automatically — the schema phase runs to completion before item writes begin.
Pages and web parts
Modern SharePoint pages are not files; they are canvas layouts with web-part objects. Treat them as structured data, not as copy-paste HTML.
For each page, the Graph pages endpoint returns a list of web-part instances with their properties (text content, image references, list references, link arrays). A competent migration walks that structure and recreates each web part by type on the destination page, not by scraping HTML.
The one category that needs extra thought is third-party SPFx web parts. If your source page uses a custom SPFx solution, the destination tenant needs the same app package installed — same package ID, same version — before the web part will render. Your migration tool cannot install the package for you (that is a tenant-admin action). What it can do is surface the missing packages in a pre-flight report so you install them before cutover.
Version history: trade-offs
Here is the honest truth about version history in a Graph-based migration in 2026: the native version stack on any newly created item starts at version 1.0. Graph does not let a third-party tool write historical versions back into an item’s native version history. That is an SPMT-only capability.
There are two reasonable responses to this. The first is: accept it and document it. For many migrations, the current-version content plus a clear note in the transition communication is enough. Nobody is going to miss version 4.2 of Q3 2021 Sales Deck.
The second is: preserve history as a sidecar. MigrationFox’s approach is to capture every source version as a JSON record per item (version number, modified-by UPN, modified timestamp, field values at that version) and write the collection to a _VersionHistory library on the destination site. The native stack on the item itself resets to 1.0, but the audit trail is intact and queryable. For regulated industries where you need to prove what a document said on March 15, 2023, the sidecar is the defensible artefact.
What you cannot do via Graph: overridemodifiedDateTimeor the originalAuthoron a new item. Both are set by the server to the service principal and the current time. Capture them in a sidecar or accept the loss. Promising otherwise is dishonest — it implies SPMT-level fidelity from a REST-only tool that cannot deliver it.
If perfect top-level metadata fidelity is a hard requirement — typically for records-management use cases with a specific retention audit — SPMT is the tool, not Graph. SPMT-equivalent migrations are on our roadmap but are not shipped today. We are telling you that so you can make the right call.
Cross-tenant UPN mapping
Tenant-to-tenant migrations almost always change user identities. Alice at acme.com becomes Alice at newcompany.com. Every permission assignment in the source references alice@acme.com; every permission replay in the destination needs to land on alice.smith@newcompany.com.
The only reliable way to do this is a mapping CSV maintained by a human who knows the org:
source_upn,destination_upn
alice@acme.com,alice.smith@newcompany.com
bob@acme.com,bob.jones@newcompany.com
marketing-team@acme.com,marketing@newcompany.com
Every source principal in the mapping has an explicit destination. Source principals not in the mapping go on an exceptions list, which the migration tool surfaces before cutover. Do not let a tool silently skip unmapped permissions — that is how sites go live with half their sharing gone and no one knows why until a user complains three days later.
For groups, remember that destination group memberships come from your directory, not from the migration. If marketing-team@acme.com maps to marketing@newcompany.com, the membership of marketing@newcompany.com must already match the intent before the permission replay runs. Provision groups and populate memberships during the pre-migration phase, not as a migration side-effect.
Post-migration: the 14-day watch
Every SharePoint migration ships with some residual surprises. The recommendation is a 14-day active watch period:
- Keep the source tenant read-only for 14 days so you can re-verify specific items if needed
- Monitor the destination tenant’s audit log for “access denied” events on migrated sites — those are permission gaps that slipped through
- Run a delta re-sync at day 7 to catch anything edited in the source after cutover (which should be zero if the source is truly read-only, but do it anyway)
- Run a final exception-list review at day 13 before you kill the source
On day 14, revoke service-principal access on both tenants, rotate any credentials involved, and archive the job report for your audit file.
Related reading
- Full SharePoint Site Migration platform page — the capability list
- SharePoint & OneDrive oversharing assessment — the audit companion
- Cloud migration checklist for IT admins — the broader programme view
Get started
Run a free pre-flight on your first site at app.migrationfox.com/register. The dry-run report will tell you what will migrate, what will land on the exceptions list, and which SPFx packages your destination tenant needs before you cut over.