Another day, another WP headache.
One of my clients contacted me saying his site is not performing properly and it has been getting worse. It's on a server I setup, so the server shouldn't be the issue, but I wanted to make sure there's not something weird going on with it, and see if I can find some causes.
He's using my CloudFlare full page caching method - so that's good. His frontend performance (for cached pages) is lightning fast. But the backend and uncached pages (and 404s) are abysmal.
I notice the standard stuff - UberMenu, Genesis theme - both very general purpose things, which we all know sacrifices performance for flexibility. UberMenu can be a beast. "I can do everything" themes often are too. Anyway, the site WAS just fine previously with those, so it's something else. In the PHP-FPM slowlog and New Relic I see "maybe_unserialize" keep coming up over and over. That function ideally would never exist if it wasn't for WP storing serialized and unserialized strings in the same places and having to detect if it's working with one or not (such an amazing design...) - but either way, it shouldn't be as slow as it is.
That function is used all over the place - but there are a couple key places to look. Especially when cron is disabled in wp-config.php and I am seeing calls to wp_get_schedule, wp_next_scheduled, and other cron-looking functions, on what seems nearly every page load. I wound up finding the culprit. The client had used a plugin called "Easy Social Metrics" and what it would do is add to the cron queue at least one row per post. So there were hundreds if not thousands of "easy_social_metrics_update_single_post" one-time cron items that were being autoloaded EVERY PAGE LOAD - because the "cron" option is an autoloaded option. So every page load inside of the WP frontend or in the admin area was loading tons of serialized text in this single variable, checking if it was serialized, unserializing it, possibly updating/modifying it, reserializing it, etc.
The sad thing was he didn't like the plugin so he had deleted it. But it left behind all the residue.
I've seen similar issues with other options, the "rewrite_rules" one was abused by some other plugin as well in the past on another site (I don't have the details anymore) but this is the second time I've had to forcefully kill off an option to actually rescue performance. Sadly, this is nothing any normal end user who is using only plugins to interact with their site would ever notice, until they installed some sort of cron manager and saw all these excess items hanging around. Not many people would install a cron manager though, or should need to. So that would just mean they have to hire someone now to diagnose why this magical CMS that can do anything is so abysmally slow.
It does have a nice looking admin interface, low barrier to entry for end users, but the foundation is horrible, the plugin and theme ecosystem seems rich because of the number of options and downloads, but the quality and performance on most are lacking.
Here's a chart of the performance. You'll see the first time I killed the "cron" option around 3:13pm, which was rewritten in full again and caused the second spike, and then when I finally purged it for good around 3:17pm. Site is back with sub-1 second average and remained that way. Which is about as good as you're gonna get with 20+ plugins including UberMenu and a kitchen sink theme. 🙂