94% of the notes on our WordPress security updates say some version of “good to go”. The other 6% is where all the work is.
The first article covered the routine path: a fresh staging copy, before-and-after screenshots, one approval, live. This one covers the rest, from the same three months and 255 site updates with one reseller partner. Three lessons came out of it, and each one changed the system rather than just fixing one site.
Lesson 1: Security Updates Need Their Own Staging Site
Most sites already have a staging copy. It is usually where a developer is halfway through something.
Run security updates there and one of two things happens. Either the update run overwrites the developer’s work, or the updates are tested against code that is not on the live site, so the screenshots prove nothing about live.
Both happened in the batches we reviewed:
- One site was declined for a month because open development work sat on its staging copy.
- One site had two staging copies, and it was not clear which one the update should be checked against.
- One site was approved from an old staging address, because the address the system used no longer resolved.
The rule now: security updates run on a dedicated copy, rebuilt from the live site for each run, on top of any staging site used for development. The two have different jobs. Development staging holds work in progress. Update staging holds an exact copy of live plus the updates, and nothing else.
A check now runs before every batch. It confirms each site’s update staging exists, that its address resolves, and that its list of test pages is set. Sites that fail are fixed the day before, not discovered during the run.
A related detail: a staging copy of a live site carries the live site’s integrations. A shop plugin on one copy was sending staging page addresses to the live ad account’s crawler. Those integrations are now switched off when a staging copy is restored.
A staging site is boring infrastructure. Having two of them is twice as boring, which is the point.
Lesson 2: Plugin Failures Fall Into Four Groups
Across the batches, the sites that needed real work were not random. The failures fell into four groups, and each group needed a system answer rather than a retry.
Inherited plugins that fight the update
Sites that move to a new host bring their plugins with them, including ones installed years ago by someone else for a reason nobody remembers.
On two sites a plugin designed to pin WordPress to a chosen version rolled core back from the current release to 6.3 during the update. The next plugin to load expected a newer WordPress and crashed, and the page came back blank. Restoring core and removing the plugin fixed each site in 23 to 70 minutes. Finding the cause was the work. The second site had been migrated in after we had already scanned for that plugin once.
On another site, a login-protection plugin blocked logins to the staging copy, so the update could not be checked. That was solved by excluding staging from the protection.
Memory-hungry premium plugins
Five sites ran out of PHP memory during the update. Each was fixed in 4 to 16 minutes by raising the limit.
The sixth was different. A premium events plugin had a bug in how it worked out ticket prices, and WooCommerce looped until any memory limit ran out. Raising the limit did not help. We patched the plugin by hand, which took about two days to track down. The next month’s update installed the vendor’s new version, overwrote the patch, and the site broke again.
The system answer: each site can now exclude named plugins from updates, separately for staging and live. A patched plugin stays patched until the vendor fixes it, and the exclusion is visible to anyone who looks at the site’s settings.
PHP version requirements
In October, plugin updates started requiring PHP 8.3. Six sites needed a PHP upgrade during that update week. The upgrades took between 26 minutes and about two and a half hours. The slow one had a staging copy that had not been refreshed in two months, so it had to be rebuilt before the PHP change could be tested.
PHP upgrades are now being folded into the update batch, so a site that needs a newer PHP gets it tested on the same staging copy, with the same screenshots, in the same run.
Premium plugins that cannot update automatically
A paid backup plugin cannot update through wordpress.org, so it stays on whatever version was installed until someone updates it by hand. The hosting already backs up every site off-server, so the plugin was a second backup system that nobody was updating. We recommended removing it. The reseller removed it from four sites in 45 minutes.
A plugin that duplicates something the platform already does is not extra safety. It is one more thing to update.
One that was not a plugin
One site’s update would not complete because the screenshot step could not capture two of its pages. They were photo galleries, one of them 214 MB. Swapping them for smaller pages in the site’s test list let the run complete 17 minutes later. The lesson there is about choosing test pages: pick pages that show the layout, not the heaviest page on the site.
Lesson 3: An Approval That Waits Needs a Deadline
“Do not push live until I say so” sounds like the careful option. Without a date on it, it is the option that can leave a site unpatched the longest.
The wait mode exists for good reasons, and the next article covers them. The problem is not the mode. It is an open end. A site waiting for an answer is a site running the old, vulnerable code, and nobody receives a reminder that the answer has not come.
The rule we are moving to: every wait gets a date, and on that date the update either goes live or becomes a conversation.
What This Adds Up To
None of these problems are exotic. They are what ten years of plugins installed by different people look like when something finally updates them on a schedule.
The routine 94% is what the process is built for. The 6% is what the process is for. Each non-routine site either became a rule (dedicated update staging, the pre-batch check, plugin exclusions, PHP in the batch) or a plugin that left the site.
If you look after WordPress sites and want to know which of these groups your sites fall into, I am happy to take a look.



