Short, plain and honest about what might break.
What to check next
Logs are the cheapest witness you have. Before anyone proposes a theory, we turn on debug logging on a copy of the site, repeat the problem once and read what it left behind. Half the time the answer is sitting there in plain words, and the other half we at least know which theories to stop discussing.
Permissions tend to drift. A role that made sense at launch picks up one extra capability each year until nobody can say who is allowed to do what. We list the roles, list the people and compare them with what the job actually needs. It is a dull hour, and it has found more real problems than most scanners.
The short version
Every feature has a running cost, even when nobody touches it. It needs testing on each upgrade, explaining to each new editor and checking in each review. When a client asks for something small, we ask who will look after it in two years. Sometimes the honest answer is that it should stay a good idea.
Clients rarely remember the clever parts. They remember whether the site stayed up, whether the invoice matched the estimate and whether someone answered when it broke. We try to write code with that in mind. A plain solution that a tired person can repair at the end of a long day beats an elegant one.
What we found first
Writing it down was the last step and possibly the most useful one. A short note about what we tried, what failed and why we stopped has saved us more time than any tool. When this comes up again, and it will, someone will search the repository, find these paragraphs and skip the whole expensive afternoon.
We started by reading the code rather than the documentation, because the code is what runs. Most of the surprises in a WordPress project live in the gap between what a function promises and what the theme actually asks of it. An hour with the templates open told us more than a week of status meetings ever had, and it gave us a list of real questions to bring to the client.
Why it matters
The first measurement is always the most useful one, even when it is rough. Write down the query count, the page weight and the time to first byte before you change anything. Without those numbers you cannot tell an improvement from a coincidence, and three weeks later nobody will remember what the site felt like before you touched it.
Caching hides problems as often as it solves them. A page that is fast only when the cache is warm is a page that falls over on the morning after a release, which is exactly when people are looking at it. Test the cold path on purpose. Clear everything, load the home page once, and read what the database had to do.
The part that surprised us
Nothing here needed a new plugin. The fix was a small change to a query and a better idea of when to run it. That is usually the case: the expensive part of a site is rarely the code you can see, and adding a layer on top only moves the cost somewhere harder to find. Delete first, then decide what is still missing.



Priya Raman Nov 02, 2026
Sending this to a colleague who is about to start a migration next week.
Aisha Khan Nov 02, 2026
Nice. One small correction: that hook fires earlier than the post suggests.
Ravi Menon Nov 05, 2026
Tried this on a client site this morning. The query count dropped straight away.
Felix Moreau Nov 03, 2026
This saved me an afternoon. The bit about testing the cold path first is going on the team wiki.
Aisha Khan Nov 03, 2026
We hit the same thing last spring and blamed the host for a month. Wish I had read this then.
Grace Tanaka Nov 04, 2026
Does this still hold on a site with a persistent object cache, or does the picture change?
Priya Raman Nov 05, 2026
Good write-up. I would add a note about checking the logs before you clear anything.
Grace Tanaka Nov 06, 2026
I disagree slightly on the rollback plan, but the rest matches what we do.