WordPress Multisite: The Questions to Answer Before You Commit
WordPress multisite shares one codebase, one database and one trust boundary. The questions to answer on hosting, backups, plugins and exit plans first.
The request always sounds harmless. “Can we add a site for the German market?” You spin up a subsite, network-activate a couple of plugins, and everyone’s happy for about eighteen months. Then the German operation gets sold, the buyer wants the site on their own hosting by the end of the quarter, and you discover there is no button in WordPress that says “extract site 7 and everything it owns”.
That moment is the real cost of a network, and it’s the one nobody prices in at kickoff. WordPress multisite isn’t a performance decision or a convenience feature. It’s a decision about what a group of sites shares permanently: one filesystem, one database, one PHP process, one set of credentials, one blast radius.
We run networks for clients and we also spend a fair amount of time pulling sites out of networks other people built. The questions below are the ones that would have prevented most of that second category of work.
- A network shares a trust boundary. One compromised subsite means a compromised network, because every site runs as the same user against the same database with the same credentials. If any site in the group has a different security posture, it doesn’t belong in the network.
- Each subsite adds roughly nine to eleven database tables. At 300 sites you’re past 3,000 tables, which turns logical dumps, per-site restores and schema migrations into real engineering problems rather than cron jobs.
- Users are global and email addresses are unique network-wide. That single constraint kills more multisite plans than hosting or performance ever will.
- Core, theme and plugin updates applied once across every site is the genuine win, and it’s a big one if you’re maintaining 40 near-identical sites with one team.
- Decide the exit path before you build. Budget half a day per site for extraction using WP-CLI table exports and a search-replace, and more if the site has serialised cross-site data.
What a network actually shares
People picture multisite as “several WordPress installs in a trenchcoat”. It isn’t. One install runs all of them and branches on the request host and path.
Shared globally: the wp-content directory, every plugin and theme file, the PHP version, the wpusers and wpusermeta tables, wpblogs, wpsite, wpsitemeta, and the object cache connection. Per-site: its own wp2posts, wp2options, wp2_terms and friends, plus an uploads subfolder at wp-content/uploads/sites/2/.
Themes have to be network-enabled before a site admin can pick one, which is actually useful for agencies. Ship one well-built theme, enable it network-wide, and let each site configure it. That’s the scenario where a flexible multipurpose theme earns its keep, because per-site differences are handled in settings rather than in forked code. We’ve run CanvasWP this way across regional sites where the brand is shared but every market wants a different layout.
What’s not shared: nothing in wp2options. Plugin licence keys, SMTP settings, analytics IDs and cookie banner config all need setting 40 times, unless the plugin stores them in wp_sitemeta. Most don’t.

The questions that actually decide it
1. Do all these sites share one trust boundary?
This is the first question and it disqualifies most candidates. Every site in a WordPress network executes with the same filesystem permissions and the same database user. A super admin on any site is a super admin everywhere. An uploaded PHP file on the smallest marketing microsite reaches the main site’s database.
So: would you give the person who manages site 12 the keys to site 1? If the honest answer is no, you want separate installs. Client sites belonging to different companies should essentially never share a network, no matter how convenient the updates are.
2. Is one global user table a feature or a bug?
Users are network-wide. Emails are unique across the whole network. If your project is “three brands, same customers, one login”, that’s a gift. If it’s “three brands, and Jane is a customer of two of them with different billing emails”, you’re going to fight WordPress for the next year.
This bites hardest on anything membership or ecommerce shaped. Separate purchase histories, separate password resets and separate account pages on a shared user table is work, not configuration. We’ve written about why membership architecture has to be decided before the build, and multisite makes that doubly true.
3. Who owns the plugin list?
On a network, nobody owns the plugin list by default, which means it grows. Site admins can’t install plugins (good), but they can request them, and the path of least resistance is to install network-wide and activate on one site. Six months later you have 60 plugins in wp-content/plugins and no record of which site needs which.
Decide upfront: either everything is network-activated and the list is short and governed, or you track per-site activations in version control. Pick one. A drifting plugin directory is the single most common reason a network becomes unupgradeable, and the cleanup looks exactly like a standard plugin audit except you have to check impact against every site.
4. Does your host really support it?
“Supports multisite” covers a lot of ground. Ask specifically: can you do a wildcard DNS record and a wildcard TLS certificate for subdomain installs? Does the staging-to-production push rewrite the wp_blogs table? Is there a hard cap on database tables or database size? Can you restore a single site from backup, or only the whole network?
That last one catches people. Most managed hosts restore the entire database. Restoring site 7 to yesterday while leaving sites 1 to 50 untouched is a manual job involving a table-level import that you should rehearse before you need it.
5. Will any site ever need to leave?
If the answer is “possibly”, write the extraction runbook on day one and test it on a throwaway subsite. If the answer is “definitely, we sell these businesses”, don’t use multisite.
Subdomains, subdirectories and mapped domains
The subdomain versus subdirectory choice is permanent in practice. You can change it, but it involves rewriting wp_blogs and every absolute URL in every site’s content, so treat it as permanent.
- Subdirectory (
example.com/de/) needs no DNS work and your existing certificate covers it. The catch: a page on the main site can never use a slug that collides with a subsite path, and plugins that assume the site lives at the domain root occasionally emit broken URLs. - Subdomain (
de.example.com) needs a wildcard A record and a wildcard certificate, which with Let’s Encrypt means the DNS-01 challenge rather than HTTP-01. Cleaner separation, slightly more infrastructure. - Mapped domains have been in core since WordPress 4.5. You do not need the old domain mapping plugin or a
sunrise.phpdrop-in for the basic case any more; set the site’s domain in Network Admin and point DNS at the server.sunrise.phpis still there for exotic routing, and most of the time you won’t need it.
One caveat on subdirectory installs: the regional SEO story is weaker than people claim. Subdirectories do consolidate authority, but if two subsites publish overlapping content in the same language, you now have an internal duplication problem that no network setting solves.
Setting up a network that won’t bite you in year two
The installer gives you five constants. Add a few more it doesn’t mention.
/ Step 1: add this alone, reload admin, then run Tools > Network Setup /
define( 'WPALLOWMULTISITE', true );
/ Step 2: what the installer prints, keep it above the "stop editing" line /
define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', true );
define( 'DOMAINCURRENTSITE', 'example.com' );
define( 'PATHCURRENTSITE', '/' );
define( 'SITEIDCURRENT_SITE', 1 );
define( 'BLOGIDCURRENT_SITE', 1 );
/ Step 3: the ones that save you later /
define( 'DISABLEWPCRON', true ); // run cron per site from the system scheduler
define( 'UPLOADSPACECHECK_DISABLED', true ); // skips a recursive disk scan on admin pages
define( 'WPCACHEKEY_SALT', 'prod-net-' ); // stops key collisions on a shared Redis instance
define( 'NOBLOGREDIRECT', 'https://example.com/404-site/' ); // unknown subdomain handling
Worth knowing before support tickets arrive: on multisite, site administrators lose the unfiltered_html capability. Only super admins keep it. The symptom is an editor pasting an embed iframe into a block, saving, and watching it vanish. Explain this to the client in week one rather than week twelve.
For cross-site data, switchtoblog() is the right tool and it’s easy to use wrongly. Resolve everything you need inside the switch, including permalinks and attachment URLs, and always restore.
/**
- Latest posts from the network's news site, cached per requesting site.
*/
function acmenetworknews( int $source_site = 2, int $limit = 3 ): array {
if ( ! ismultisite() || getcurrentblogid() === $source_site ) {
return [];
}
$key = "acmenews{$sourcesite}{$limit}";
$items = wpcacheget( $key, 'acme_network' );
if ( false !== $items ) {
return $items;
}
switchtoblog( $source_site );
$items = array_map(
static fn( WP_Post $p ): array => [
'title' => getthetitle( $p ),
// get_permalink() must run inside the switch or you get the wrong host
'url' => get_permalink( $p ),
],
get_posts( [ 'numberposts' => $limit ] )
);
restorecurrentblog(); // never switchtoblog() back manually, the stack matters
wpcacheset( $key, $items, 'acmenetwork', 5 * MINUTEIN_SECONDS );
return $items;
}
The operational tax nobody budgets for
Every WP-CLI command needs a --url flag or it silently targets the main site. That trips up every developer new to the network, usually while running a search-replace.
# Run due cron for every site, sequentially (wp-cron is disabled in config)
wp site list --field=url | xargs -n1 -I{} wp cron event run --due-now --url={}
Dump one site's tables only, for an extraction or a targeted restore
wp db export site-7.sql \
--tables="$(wp db tables 'wp7*' --all-tables-with-prefix --format=csv)"
That cron loop is linear. At 20 sites it finishes in seconds. At 400 sites with WooCommerce and Action Scheduler on half of them, it won’t finish before the next run starts. You’ll need to shard it or move to per-site scheduled jobs.
Debugging gets harder too, because “the site is slow” now means “which of these 60 sites, and is it the site or the network?”. Query Monitor works fine per site, but you’ll want network-level APM as well. The isolation process we use for single installs still applies, with one extra step: confirm whether the problem reproduces on a second subsite before you touch any code.
Price the maintenance honestly. A network is cheaper per site to update and more expensive per site to troubleshoot. If you’re building a maintenance retainer around one, the per-site restore clause is the part to get right in writing.
The multisite pros and cons, without the sales pitch
Honest ledger, based on networks we actually run.
Worth it when: one organisation, one team, one codebase, 10 or more sites that are structurally similar. University departments. Retail chains with location sites. A SaaS product that provisions a site per customer. Multi-language setups where each language genuinely needs its own editorial team rather than a translation layer.
Not worth it when: fewer than about five sites, or the sites belong to different clients, or they need materially different plugin stacks, or any of them handles payments and personal data the others don’t, or one of them is likely to be sold, spun off or moved.
The honest middle ground is separate installs managed with a shared toolchain: Composer-managed dependencies, the same theme as a private package, and MainWP or similar for one-click updates across the fleet. You lose the single-update convenience and the shared user table. You gain independent backups, independent restores and the ability to hand any site over in an afternoon. For agencies with 30 small clients, this is nearly always the better answer and the one we recommend most often.
The exit plan, written before you need it
Extraction is mechanical if you prepared and archaeological if you didn’t. The working method:
- Export the site’s tables with the WP-CLI command above, plus the rows for that site’s users from
wpusersandwpusermeta. - Copy
wp-content/uploads/sites/N/into the new install’swp-content/uploads/. - Import into a fresh single-site install and rename the tables from
wp7towp_. - Fix capability meta keys. They’re stored as
wp7capabilitiesandwp7user_leveland need renaming, or nobody can log in. - Run
wp search-replacefor the old URL, then again for the uploads path, with--preciseif you have serialised data from page builders.
Step four is the one everybody forgets. Step five is where serialised option values from builders and sliders go wrong, which is another argument for keeping content in native blocks.
Frequently Asked Questions
Is WordPress multisite slower than separate installs?
Not per request, no. Page rendering performance is essentially identical because only one site’s tables are queried on a given request. What does degrade is anything that touches all sites at once: network admin screens, the sites list, network-wide searches and plugin update checks all scale with site count, and they get noticeably sluggish somewhere past a few hundred sites.
Can I run WooCommerce on a multisite network?
Yes, and WooCommerce works correctly on each subsite, but it isn’t a multi-store product. Orders, products and settings stay per site, licences are usually per site anyway, and Action Scheduler runs independently on each store, which can saturate a shared cron loop. If the stores need shared carts or shared customer accounts across brands, multisite will not give you that.
Do I still need a domain mapping plugin?
No, not for standard cases. Core has supported multiple domains per network since WordPress 4.5, so you set the domain directly in Network Admin and point DNS at the server. A sunrise.php drop-in is only needed for unusual routing logic, and if you think you need one, check whether core already handles it.
How many sites can one network realistically hold?
Thousands, with the right infrastructure, but the practical ceiling for a normal managed host is lower than that. Each site adds roughly nine to eleven tables, so 500 sites means around 5,000 tables, and logical dumps plus schema migrations start taking real time. If you’re planning for more than a few hundred sites, budget for a database you control rather than a shared managed plan.
Can I convert an existing single site into a network later?
Yes, and it’s much easier than converting back. Add WPALLOWMULTISITE, run Tools then Network Setup, and your existing site becomes site 1 with its tables untouched. The one constraint worth checking: subdirectory installs are blocked by the installer on sites more than a month old, so an established site typically has to go subdomain.
Make the call on the trust boundary first. If every site belongs to the same organisation, is maintained by the same people, and will plausibly still be in the group in three years, a network will save you real hours every month. If any one of those is shaky, build separate installs and spend the saved effort on a decent deployment pipeline instead. And whichever way you go, write the extraction runbook now, while you still remember how the thing is wired.


