A WordPress site with 250k visits/month that was crashing with 502s, eaten by invisible bots, and with a bug-filled theme. In 4 days: zero crashes, attacks blocked, performance recovered.
CHAPTER 1
The client reported vague symptoms: "wp-admin is super slow", "sometimes the site throws an error", "the editor hangs when saving". Without observability, that's all the owner can describe — symptoms, not causes.
We activated an event-capture mu-plugin (which later became Pulse) and in the first 24 hours we saw the full picture:
Human level: the site fails 1 in every 100 visitors — and you don't know when or who.
Technical level: PHP-FPM takes more than 60 seconds to respond and nginx throws upstream timeout.
Human level: your site keeps writing to an error file nobody reads. It's disk not used for serving.
Technical level: PHP 8 warnings from accessing array offset without validation.
Human level: 1 in every 20 visitors waited more than 10 seconds for a page to load.
Technical level: P95 percentile at 10,730ms — borderline timeout in many cases.
Human level: half a gigabyte of junk in the database that every query has to navigate around.
Technical level: wp_options tables + unrotated logs consuming space + I/O.
CHAPTER 2
While analyzing the logs, one IP appeared making a very strange pattern. Each request took 23 to 34 seconds and generated 3,000+ SQL queries. It was an SEO spam bot abusing the WordPress search engine, hitting it with URLs like:
/page/61?s=news+am+cleantalkorg2.ru+World+News+The+New+York+Times+Breaking+News...
The real cost: ~5 minutes of PHP-time spent per hour on spam. That's 1 worker permanently occupied by a bot. Meanwhile, real visitors were waiting in queue.
The attack had been active for weeks. Pulse found it in 1 hour.
CHAPTER 3
The theme had the same bug repeated 21 times across 11 different files. Accessing an array key without first checking the array existed. PHP 8 throws a warning. The warning goes to disk. Multiplied by thousands of visitors.
$thumb = wp_get_attachment_image_src(...);
$thumb = filter_var($thumb[0], FILTER_VALIDATE_URL)
? $thumb[0]
: 'fallback.jpg';
If $thumb is false (the post has no image), accessing $thumb[0] triggers a PHP 8 warning.
$thumb = wp_get_attachment_image_src(...);
$thumb_url = (is_array($thumb) && isset($thumb[0]))
? $thumb[0] : '';
$thumb = filter_var($thumb_url, FILTER_VALIDATE_URL)
? $thumb_url
: 'fallback.jpg';
No warnings. No overhead. Bonus: we added esc_url() in other places — free XSS mitigation.
The same error was copied into 11 theme files. Any of them could trigger it.
CHAPTER 4
A cron event appeared consuming almost 70 full seconds. But WordPress doesn't tell you which hook is slow inside a cron run — it only tells you the wp-cron.php file took N seconds. We built a profiler that captures per-hook timing, and on the first slow cron we caught the culprit:
The first hook consumed 99% of total time.
memberful_wp_cron_sync
Root cause: the Memberful plugin syncs with its API pulling all members each time (non-incremental).
Recommended fix: lower cron frequency, or move to Action Scheduler to run in background without blocking user-facing PHP workers.
Without Pulse's cron profiler, this would be invisible. Wordfence doesn't see it. Sucuri doesn't see it. New Relic would cost $99+/month.
CHAPTER 5
The site had Wordfence Free installed. People assume they're protected. But Wordfence Free doesn't detect behavioral patterns — it only blocks based on a list of known signatures. Modern attacks are behavioral, not signatures.
The radar shows how much each solution covers.
Good for: login lockouts, malware scanner, basic IP reputation.
Did not block: the 5 attack types most affecting this site.
Good for: all of the above + behavioral firewall, custom rules, 16-signal bot scoring, slow request tracking.
Blocked: the 5 attacks Wordfence missed.
Day 1: only Wordfence (5/h). Day 3+: Shield active (80–122/h).
CHAPTER 6
This is the real evolution, metric by metric, over the 4 days of optimization. Each deploy was reflected in the latency percentiles.
P50 (typical), P95 (worst 5%), P99 (worst 1%), AVG (average).
Zero 5xx per day since Day 2.
From ~50/h to essentially zero.
Direct comparison of percentiles.
The 7% of 403s are attacks blocked by Shield. The 200s are happy visitors.
CHAPTER 7
Security plugin logs not rotated (568 MB), AdRotate trackers (177 MB), tables with years of accumulated overhead. Every MySQL query had to navigate this dead weight. We identified and cleaned it in batches.
These MB are not useful data. They are blank pages between rows.
FINAL RESULT
Without observability, you can't see it. Without seeing it, you can't fix it. The cleantalkorg attack had been active for weeks. The 21 theme bugs were generating constant noise. The Memberful cron had never been diagnosed. All of that was invisible to Wordfence, to the client, to WP Engine's logs. Once visible, the solutions took hours, not weeks.
WANT THE SAME FOR YOUR SITE
Join the waitlist. The first 500 get 50% lifetime discount and private beta access.
Join the list