Migrating a WordPress multisite network
A WordPress multisite network hosts several subsites from a single installation. Migrating this kind of network adds a constraint a simple site doesn’t have: each subsite has its own content structure, and a global URL replacement breaks more than it fixes.
What a multisite network adds compared to a simple site
A multisite network relies on a MULTISITE constant enabled in wp-config.php, and on a table that lists every subsite in the network with its associated domain or subdomain. Each subsite has its own content tables, prefixed with its own numeric identifier, but the whole network shares one common network-level user table: a user account created on the network can access several subsites without being duplicated.
Plugins add a further distinction to check before migrating: a plugin can be “network activated”, in which case it automatically applies to every subsite including ones created afterwards, or activated individually on a single subsite. This distinction doesn’t show up in the plugin’s own files, only in the network’s activation settings, which is why a prior inventory matters — otherwise a subsite can turn up missing a feature only after the switch.
This setup is stable and has been documented for a long time, but it directly changes how a migration has to run: there isn’t one content database to handle, but as many content structures as there are subsites, linked together by the network’s domain mapping table.
What a multisite migration adds
- A network domain and subdomain mapping table to update, in addition to the content tables
- A URL replacement that must run subsite by subsite, since wp search-replace’s --url option targets one specific subsite, not the whole network at once
- Subsites that may have different active themes or plugins from one to another, to check individually
- A network primary domain whose switch affects access to every subsite, not just one isolated site
How I run a multisite migration
-
Subsite inventory
I list every subsite in the network, its current domain or subdomain, and its own plugins or themes, noting which ones are network-activated rather than activated individually.
-
Full copy to a test environment
The files and database for the whole network are duplicated to a test environment before any URL change.
-
URL replacement subsite by subsite
I run wp search-replace with the --url option targeting each subsite individually, rather than a global replacement across the whole network.
-
Checking each subsite
I check that each subsite responds correctly with its new URL, that its settings and menus display normally, before moving to the next one.
-
Switching the primary domain
The network’s primary domain is only switched once every subsite has been individually checked, never before.
Related reading
-
Zero-downtime host migration
The full detail of the PHP serialisation mechanism.
-
Domain name change
A related case, on a simple site this time.
-
Understanding PHP serialisation
The full definition of the mechanism and its pitfalls.
-
Backing up your shop before any work
What to back up before any network migration.
Describe your need in one minute
A few targeted questions so I can reply with an estimate rather than another questionnaire.