A 15-second WordPress site that plugin-disabling could not fix. The bottleneck was 4.2 million orphaned rows in wp_options. Page load went from 12 seconds to 1.8.
5 September 2026 · 2 min read
SECTOR
Shared hosting provider
SCALE
~150 accounts on a single node
PLATFORM
CloudLinux, LiteSpeed, MySQL 5.7
ENGAGEMENT
Performance investigation
Page load, down from 12 s
Options query, down from 3.4 s
Orphaned rows cleared
Scroll the diagram sideways to see all of it →
The bar that matters is the second one: the query, not the page.
Normal traffic, abnormal load times. A customer reported their WordPress site loading in 12 to 15 seconds despite entirely normal traffic volumes. The hosting provider suspected a plugin, but disabling plugins made no visible difference.
The bottleneck was not in PHP. We profiled the request lifecycle and found the cost was MySQL query time. The slow query log showed a single query against the wp_options table taking 3 to 4 seconds on every page load. That table had grown to 4.2 million rows, courtesy of an abandoned transient caching plugin that had never cleaned up its expired entries.
When disabling every plugin changes nothing, the problem has outlived the plugin that caused it.
Millions of orphaned autoload rows. wp_options held 4.2 million orphaned autoload=yes transient rows. Every single page load triggered a bulk SELECT across autoloaded options, overwhelming the buffer pool and forcing disk reads on every request. No amount of plugin toggling addresses that, because the rows outlive the plugin that created them.
12–15 second page loads at normal traffic; disabling plugins changed nothing.
Profile the full request lifecycle, then read the slow query log rather than guessing.
1.8 s page load, 12 ms options query, with row-count alerting to prevent recurrence.
Clear the rows, remove the source, alert on the drift. We cleaned the orphaned transients out of wp_options, removed the abandoned plugin and optimized the table to reclaim space, then verified the autoload row count was back in a healthy range. A cron check now alerts on wp_options row count growth so the same drift cannot build up unnoticed.
12 seconds to 1.8 seconds. MySQL query time for the options load fell from 3.4 seconds to 12 milliseconds.
When disabling plugins changes nothing, the answer is in the query log. We profile the whole request path and fix the actual bottleneck.