In short

Sites cloned from one template share their faults as readily as their fixes. Update paired plugins together, land every change on one site first, check real pages instead of server health, verify protection form by form, and expect clones to carry the old location's name.

There is a particular kind of quiet that comes before a bad morning. The dashboard is green. The servers answer. Nobody has messaged you yet. Then somebody does, and the message is not “one of the sites is down”. It is “all of them are”. If you are managing multiple WordPress sites cloned from one template, that message is the one to plan for.

That was me, on a spring morning in 2026, looking at a network of local sites for a multi-location service business I build and run. Each site serves one area. Each has its own domain, its own address and phone number, its own pages written around that location. And every one of them was cloned from a single master template on a popular page builder, then kept as lean as that stack allows.

That shared origin is the whole point of the network. Tune the template once and every location gets faster. Fix a layout once and every location looks better. Open a new market and most of the work is already done. What I learned that morning, and several times afterwards, is that the same property works in both directions. Reuse and blast radius are not two features of a fleet. They are one feature, seen from two sides.

Every site went down at once, because they were built to be the same

The symptom was simple. Every site in the network returned an error instead of a page. Not slowly, not intermittently. Down, together.

The dig was short once I was on the server. The page builder comes in two parts: the free core and a Pro add-on that extends it. The core had updated itself automatically overnight, through the central tool I used to keep the fleet current. The new core release removed a class that the installed add-on still depended on. When WordPress loaded the add-on, PHP reached for that class, found nothing, and stopped with a fatal error. WordPress never finished starting, so there was no page to serve and no admin screen to log in to.

A compatible add-on release did appear, roughly an hour after the core update had already gone out. That hour was outside anyone’s control. What was inside my control was the fact that the update had gone to every site at the same moment, because to the update tool they were simply the same site several times over.

The fix itself was mechanical. With the admin unreachable, I disabled the add-on at the filesystem level, installed the compatible release on each site, corrected file ownership and reactivated it from the command line. The network was back the same day. The clean-up was not quite finished, though: working at the filesystem level left duplicate plugin folders behind on some sites, which I only found and removed during a later sweep. A fix made underneath the application leaves debris underneath the application.

The servers were up the whole time

This is the detail I keep coming back to. Throughout the outage, every server was healthy. CPU was fine. Memory was fine. The web server answered requests. A monitoring dashboard that checks whether machines are alive would have shown green from start to finish.

The failure lived one layer higher, inside the application, and the only way to see it was to ask each site for a real page and read what came back. So that is now the check after any change: a real request against every site in the network, looking for a real page, not a dashboard confirming that the hardware is breathing. It sounds obvious written down. It was not what I was doing before.

An update reaches the network only after one site has survived it

The same mismatch came back later. A routine fleet update moved the core ahead of the add-on again. That time nothing fell over, but the gap was the same gap, and luck is not a process.

So the rule is now fixed. The builder and its add-on move in lockstep and are never updated independently. Before the core moves, I confirm that a compatible add-on release exists. An update goes to one site first, and I watch that site before the change reaches the rest. Only then does it go wide, and only then does the real-request check run across the whole network.

None of this makes updates slower in any way that matters. It makes the first site pay for a mistake instead of all of them.

Pro tip

If a plugin has a companion or Pro add-on from a separate source, treat the pair as one package. Pin them together, update them together, and check that the add-on supports the new core version before either one moves. Automatic updates for one half of a pair are an outage with a timer on it.

The attack on one site came from an unprotected form on another

The second episode did not take anything down. It looked, at first, like something much worse.

Junk enquiries started arriving in the sales team’s lead channel. Fake names, fake email addresses, phone numbers that were plainly not local. They carried no landing page, no journey, no service. The reasonable reading was that somebody was attacking another of the client’s sites, and I was asked to check that site’s server logs.

That site was the wrong place to look. Its logs did hold an unrelated stream of failed login attempts, which made it look even more like the target. But none of that matched the junk leads.

What matched was the lead pipeline itself. By lining up the time each junk lead arrived with the requests that created it, and reading the full request the automation layer had stored for each one, I could see which site had sent it and which form. It was a call-back popup on the local sites. That one form had no spam protection. Every other form on the same sites had it. The popup was the single gap, and a bot had found it.

The real cost was not the noise in a chat channel. Each junk submission opened a real record in the sales pipeline, the same as a genuine customer would. That is a cost the sales team carries, and it hides real leads among fake ones.

The fix was to add the same protection the other forms already had, copied field for field from a form that was known to work. Before I switched it on, I proved each site’s protection key against the verifying service, because a wrong key would have rejected every genuine enquiry without a sound. A spam fix that silently blocks customers is worse than the spam.

A fleet is only uniform where somebody checked

The lesson here is uncomfortable, because it cuts against the reason the network exists. I thought of the sites as identical. In most respects they were. But “identical” was an assumption about all of them, built from checks on some of them.

Protection is per form, not per site. Knowing that a site has spam protection tells you that at least one of its forms does. So protection is now verified form by form, across the network, by looking at what each form actually carries. Not by trusting that a template was right when it was copied.

Field note

The search that reported the wrong forms as unprotected

My first sweep looked for the word “honeypot” in each site’s rendered HTML. It reported several perfectly protected forms as bare. The page builder names that hidden field after its own internal hash, not after what it does, so a text search for the obvious word misses it.

I had to identify the protection by the field’s type instead of its name. A check that goes red on healthy forms is almost as dangerous as one that goes green on broken ones, because the next time it goes red, somebody will ignore it.

A find-and-replace carries the old location into the new one

The third episode was slower and, in some ways, more expensive, because it never announced itself.

New location sites were made by cloning an existing site and replacing the location name. On the surface that works. The headings change, the page titles change, the obvious copy changes. Underneath, it leaks.

One site carried hundreds of mentions of neighbouring locations in its copy. Shared templates on several sites linked to pages that existed on only one of them, so a visitor clicking a perfectly reasonable link landed on an error. Image records were renamed in the database while the files on disk kept the old location’s name, so the site asked for pictures that did not exist.

Part of the reason is how page builders store content. The layout is saved as structured data with escaped characters inside it, so a plain text search can report success while missing strings that are stored in a different shape. I learned to match that data on its structure rather than on its text, and to replace whole values rather than fragments.

Every fix was repeated by hand, and the copies drifted

This is where the fleet model showed its other cost. Each of these problems had to be fixed once per site. Nothing propagated a correction automatically, because the sites had stopped being connected the moment they were cloned.

And the copies drifted. Code that was meant to be the same on every site turned out, when I compared it, to have quietly forked in places. A fix applied to “the shared version” would not reach a site whose copy had changed, and nothing would warn me. The phrase “the shared version” did not describe anything real.

So the network had the worst of both arrangements. An automatic update could break every site at once, because they were the same. A manual fix had to be carried to every site by hand, because they were not.

The channel that spreads a fix must not also spread a break

Put the three episodes side by side and one principle comes out of them. When sites share an engine, a fix spreads exactly as fast as a fault. The same mechanism carries both.

You cannot remove that property without removing the benefit. What you can do is design the operation so that the mechanism which spreads a change has a gate in it. A change reaches one site, gets looked at, and only then reaches the rest. A check runs against the thing people actually use, not against the thing underneath it. And uniformity is something you measure, not something you remember deciding.

That is most of what changed. Not the sites themselves, but the order in which things are allowed to happen to them.

If you run several similar sites, check each one as a stranger would

If you look after more than one site built from the same template, a few habits will save you the mornings I had.

Start by listing the parts of your stack that come in pairs or families, such as a builder and its add-on, or a theme and its companion plugin, and make sure they can only move together. Turn off automatic updates for anything in such a pair, and choose one site as the place every update lands first. Give it a day before the rest follow.

Then change what you count as proof. After any change, request a real page from every site and read the result, rather than relying on an uptime monitor that only knows whether a server responds. Go through your forms one at a time and confirm what protection each one carries, because the gap will be in the form nobody opened. When you clone a site, search the new one for the old one’s name in its content, its links and its file names, and expect to find it.

Finally, compare your supposedly shared code across sites now and then. If two copies differ, find out why before you trust either of them.

The risk lives in the channels between the sites

The honest end of the story is that none of this says a fleet of near-identical sites is a bad idea. It can be a very good one. Every location got faster the day the template got faster, and a new location started from a working site instead of a blank page.

What the network taught me is where the risk actually lives. Not in any one site, but in the channels between them: the update tool, the cloning step, the template everybody trusts. Those channels are what a fleet really runs on, and they deserve the same care as the sites themselves.

The thing that makes a fleet cheap to grow is the same thing that makes it fall over in unison. Build the gate before you need it.