← Back to blog

How to configure WordPress multisite (and which choices you cannot undo)

The SandyWP team 9 min read

Configuring WordPress multisite is four mechanical steps and one real decision. The steps are a constant in wp-config.php, a run through Tools → Network Setup, six more constants, and a rewrite rule.

The decision is subdomains or subdirectories, and by the time you reach that screen WordPress may have already made it for you. This post covers both, and specifically the part the guides skip: the exact conditions under which core removes an option from you, and why.

The four steps, in order

Nothing here is hard. It is worth having in one place before the interesting part.

1. Turn the feature on. Add this to wp-config.php, above the /* That's all, stop editing! */ line:

define( 'WP_ALLOW_MULTISITE', true );

That does not create a network. It only makes Tools → Network Setup appear.

2. Deactivate your plugins. Core asks for this before the setup screen, and it is worth doing rather than working around. A plugin that filters rewrite rules or home during the conversion produces a network with wrong URLs baked into the database.

3. Run Tools → Network Setup. You pick subdomains or subdirectories, name the network, set the network admin email, and click Install.

4. Paste in what it gives you. Core hands you a block of constants and a rewrite block. The constants look like this, and they come straight out of core's own template in wp-admin/includes/network.php:

define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', false );
define( 'DOMAIN_CURRENT_SITE', 'example.com' );
define( 'PATH_CURRENT_SITE', '/' );
define( 'SITE_ID_CURRENT_SITE', 1 );
define( 'BLOG_ID_CURRENT_SITE', 1 );

SUBDOMAIN_INSTALL is the decision, written down. Every other constant on that list is bookkeeping.

You then log in again, because the conversion changes the cookie scope and drops your session.

Why the setup screen sometimes gives you no choice

This is the part people hit and do not understand, so here is the actual mechanism rather than a summary of it.

Core decides whether to offer you each option with two functions in wp-admin/includes/network.php. They are short enough to read in full, and reading them answers most of the questions people ask about this screen.

allow_subdirectory_install() ends with this query:

$post = $wpdb->get_row( "SELECT ID FROM $wpdb->posts WHERE post_date < DATE_SUB(NOW(), INTERVAL 1 MONTH) AND post_status = 'publish'" );
if ( empty( $post ) ) {
	return true;
}

return false;

Read that carefully, because it is not the rule everyone repeats. The check is not the age of your install: it is whether a published post older than one month exists anywhere in wp_posts.

So a site you installed two years ago with nothing published on it still gets the subdirectory option, and a site you installed yesterday, into which you imported an archive of old posts, does not.

The guides say "sites older than a month must use subdomains", and that is a reasonable shorthand that is wrong in both directions.

The reason for the rule is real, and core's own help text says it plainly: "The choice of subdirectory sites is disabled if this setup is more than a month old because of permalink problems with /blog/ from the main site."

In a subdirectory network the main site's posts have to move out of the way so that example.com/site2 can belong to a subsite instead of a post. Core's warning on that screen is blunt about the cost: "The main site in a sub-directory installation will need to use a modified permalink structure, potentially breaking existing links."

That is the whole rule. A site with old published posts has old published URLs, and a subdirectory network would break them.

The other function, which nobody mentions at all

allow_subdomain_install() is the mirror image, and it is the one that catches local developers:

$home   = get_option( 'home' );
$domain = parse_url( $home, PHP_URL_HOST );
if ( parse_url( $home, PHP_URL_PATH ) || 'localhost' === $domain || preg_match( '|^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$|', $domain ) ) {
	return false;
}

return true;

Three conditions kill the subdomain option: your home URL has a path, the host is exactly localhost, or the host is a bare IP address.

The first one is the common case. If WordPress lives at example.com/wp/ or localhost/mysite, parse_url returns a path and subdomains are off the table. Core tells you so in one sentence on the screen: "Because your installation is in a directory, the sites in your WordPress network must use sub-directories."

This is why a network you configure on a local install in a subfolder can come out structured differently from the one you configure on the server, without either screen looking unusual.

Neither screen is broken. They are answering different questions about different home values.

There is one more piece of hidden behaviour worth knowing, in wp-admin/includes/network.php again. When neither radio is posted yet, core pre-selects subdomains if it can detect Apache's mod_rewrite, with the comment // Assume nothing. on the line.

The default you see selected is a guess about your web server, not a recommendation.

Overriding the one-month rule, and when that is fine

There is an escape hatch, and it is a documented constant rather than a hack:

define( 'ALLOW_SUBDIRECTORY_INSTALL', true );

allow_subdirectory_install() checks it before it runs the query, so setting it puts the subdirectory option back on the screen. There is also an allow_subdirectory_install filter that does the same thing.

Whether that is safe depends entirely on a question core cannot answer for you: are the old published URLs on the main site load-bearing? If the site has been live and linked to, forcing subdirectories to save yourself some DNS work is how you end up doing a redirect audit you did not budget for.

If the old posts are an import, a demo dataset, or a staging copy nobody links to, the constant is exactly the right tool.

Which one to actually pick

Subdirectories are the better default for most networks. One hostname, one certificate, no DNS work, and the subsites inherit the parent domain's existing standing.

Subdomains are right when the sites are meant to read as separate properties, when a subsite may later move to its own domain, or when something in your stack already needs per-site hostnames.

The operational cost of subdomains is the part to check before you commit. You need a wildcard DNS record, which core states on the setup screen: "You will need a wildcard DNS record if you are going to use the virtual host (sub-domain) functionality." You also need a wildcard certificate, and not every host issues one.

Both of those are things to verify on your actual host before you pick, not after.

What "you can switch later" really costs

You can switch. Core's own advanced administration docs say so, with the caveat attached: you can reconfigure the network "after installation, despite the advice on the screen, but reconfiguring it might not be easy."

Flipping SUBDOMAIN_INSTALL is one line, and it is the smallest part of the job.

Every subsite has a domain and a path row in wp_blogs, every one of them has its own home and siteurl option in its own options table, and every absolute URL your editors ever pasted into post content is still pointing at the old shape.

The Pressable guide to switching (about 2,500 words, read 2026-09-10) is a fair representation of the real work: backups, the constant, network admin URL edits, a database search-replace, DNS, then caches. Its own summary calls it "a significant undertaking" requiring "strong technical expertise".

So treat the switch as possible but expensive, and treat the initial choice as the thing to get right. Which brings up the obvious move.

Configure it once on a throwaway network first

The decision is cheap to make and expensive to reverse, which is exactly the shape of problem a disposable install solves. Build the network you think you want, look at it, and throw it away.

That is not just about the radio button. The things that surprise people are downstream of it: what the main site's permalinks turn into, where the network admin lives, which of your plugins have a Network Admin screen and which quietly do not, and whether your theme's assets still resolve under /site2/.

In SandyWP you tick Multisite at create time and get a real subdirectory network, on real MySQL, with WP-CLI available over SSH. It is a genuine install rather than a simulation, so wp site list and wp site create behave the way they will on the server.

If you already have a site and want to try the conversion on a copy rather than on the original, the Cloner copies a production site into a sandbox and only ever reads the source. Converting that copy to multisite tells you what the conversion does to your real content, on your real permalink structure, with nothing at risk.

Once you have a network shaped the way you want, save it as a template so the next one starts there instead of at step one.

What a sandbox will not settle for you

Being straight about the limits, because the whole point of testing a decision is knowing which part you actually tested.

SandyWP creates subdirectory networks only. Subdomain networks need wildcard DNS and per-subsite TLS, which do not fit one hostname per sandbox, so we do not offer them and a subdomain network is rejected on import rather than silently converted.

If you are leaning towards subdomains, a sandbox will tell you nothing about the DNS and certificate half of that choice.

It will also not tell you about scale. A network of three subsites does not surface the queries that get slow at 300, and it never will.

And it cannot answer the redirect question. Whether your existing URLs matter is a question about your traffic and your inbound links, not about WordPress.

The short version

Four steps: WP_ALLOW_MULTISITE, deactivate plugins, Tools → Network Setup, paste the constants back.

One decision, SUBDOMAIN_INSTALL, which core may take away from you. Subdirectories disappear when a published post older than a month exists, not when the install is old.

Subdomains disappear when home has a path, or the host is localhost or an IP.

Subdirectories are the safer default. Subdomains cost you wildcard DNS and a wildcard certificate, so confirm your host does both before you pick.

And build one on something disposable first. Reversing this decision is a database search-replace and a redirect audit; making it correctly the first time is a radio button.

If you build networks for clients regularly, the agency workflow covers the rest of the environment matrix. If you are testing plugin behaviour rather than network structure, testing a plugin on multisite is the routine for that.

Sources fetched 2026-09-10: WordPress core wp-admin/includes/network.php and wp-admin/network.php from the WordPress/WordPress mirror, the Create a Network advanced administration page, Codeable's subdomain vs subdirectory guide, and Pressable's switching guide.