WordPress Image Optimization Case Study: The Website That Was Attacking Itself
- WP Guy News, our own WordPress security and vulnerability reporting site, had three separate problems invisible to every dashboard, on top of a genuine WordPress image optimization failure.
- 58,698 optimized images were generated and stored, but never delivered to a single visitor, because one setting was off, silently, for months.
- A caching plugin’s preload feature was crawling the entire 15,000-page site every four hours, forever. Roughly 15,000 requests a day came from the server hitting itself, 40 percent of all traffic to the site.
- Fixing image delivery the obvious way broke lazy loading and made mobile speed worse. We caught it because we measure after every change instead of trusting a settings screen.
- Desktop performance went from 49 to 100. What a reader downloads scrolling the homepage dropped 87 percent, from 5.4MB to 0.7MB.
Three Problems, Zero Dashboard Warnings
WP Guy News, our own WordPress security and vulnerability reporting site, generates traffic patterns that would be unusual for most sites: continuous automated publishing, a media library past 15,000 images and 23GB. It runs a premium image optimizer on an unlimited plan, a premium caching plugin, and had a respectable speed score. Every dashboard reported success.
Underneath, three separate things were wrong, and none of them would have shown up on a normal scan.
Problem One: 58,698 Images Nobody Ever Saw
The image optimizer had been generating a lightweight modern-format copy of every image for months. Not one was ever served. The setting that tells WordPress to actually deliver those files was switched off, so the plugin created them, stored them, reported success, and served the original heavy files to every visitor anyway.
Conversion for new uploads was off too. On a site that publishes daily, the gap widened every day it went unnoticed.
We found it the same way we find everything: by testing what a real visitor’s browser actually receives, not by reading the optimizer’s own report. Every image on the homepage was still arriving as a heavy JPEG or PNG, in a browser fully capable of accepting a modern format. The plugin’s own dashboard showed thousands of successful conversions and gave no indication that not one of them had ever reached anyone.
Problem Two: The Site That Was Attacking Itself
This was the big one, and it took reading 2.9 million lines of server log to find it.
The clue was not in any dashboard. It was in 79 days of raw access logs. We pulled every request by IP address and looked for a pattern a real visitor would never produce. One address stood out immediately: the server’s own IP, requesting a full page render roughly every five seconds, around the clock, for weeks at a stretch.
Cross-referencing that pattern against the caching plugin’s settings gave the answer. Preload was set to crawl the entire site on a schedule, and the cache was set to clear every four hours. On a site with 15,000 pages, a full crawl at that pace never finishes before the cache clears and the crawl starts over. Clear the cache, start crawling, never finish, clear the cache again, forever.
The total: 1,176,276 requests over 79 days from the server’s own IP address, roughly 15,000 a day. Forty percent of all traffic to this site was the site attacking itself. Add another 600,000 requests from SEO and AI crawlers, and over half the server’s work was being done for nobody.
That server also hosts other client sites. They were paying for this too.
Problem Three: The Fix That Made Things Worse
Turning on modern-image delivery the obvious way, through the plugin’s own built-in method, silently disabled the site’s lazy loading. The image plugin’s markup and the caching plugin’s lazy-loading feature do not cooperate. Images that used to load only when a visitor scrolled to them started loading all at once instead.
Smaller files, but far more of them upfront. Mobile paint time went from 2.2 seconds to 4.0 seconds. Worse than before we touched anything.
We caught it because we measure after every change instead of trusting a settings screen, and switched to a server-level approach that delivers modern images without touching the page markup at all. That version tested better than either previous state.
What We Actually Did
Once both root causes were confirmed, the fix list was straightforward:
- Stopped the self-crawl: preload disabled, the 4-hour cache-clearing schedule widened to 10 days, and 21,388 queued crawl URLs cleared out, backed up first.
- Put the site behind Cloudflare with a cache rule that caches pages at the edge, verified for real visitors and correctly bypassed for logged-in editing. Server response time roughly halved, and crawler traffic now stops at the edge instead of reaching the server at all.
- Delivered the 58,698 modern images the right way, at the server level, so every file became useful without breaking lazy loading.
- Verified everything from the outside: every image checked for correct rendering, logged-in sessions confirmed uncached, payload measured through a full scroll like a real reader would experience it.
WordPress Image Optimization: Before and After
The numbers below come from the same testing standard we use on every site: GTmetrix Lighthouse, iPhone simulation on a throttled connection for mobile, desktop tested separately, measured before and after every change. These are not projections. Every number was measured on the live site, before the fix and again after, using the exact same test conditions both times.
| Before | After | |
|---|---|---|
| Desktop performance score | 49 | 100 |
| Desktop main-content paint | — | 592ms |
| Mobile performance score | 74 | 78 |
| Mobile main-content paint | 2.18s | 1.97s |
| Homepage scroll payload | 5.4MB | 0.7MB (-87%) |
| Optimized images sitting unused | 58,698 | 0 |
| Self-inflicted requests per day | ~15,000 | 0 |
Why This Matters
Every one of these three problems passed every check available. The optimizer dashboard said optimized. The caching plugin said working, and its preload feature, marketed as a performance feature, was the single largest source of load on the server. The speed score said B.
The tools on a website report on themselves. None of them measure what a visitor actually receives, and on this site, one of those tools was quietly costing more than everything else combined.
That is exactly the gap a Titanium care plan is built to close: not trusting a green checkmark, measuring what actually happens.
For most site owners, none of these three problems would ever surface on their own. They only show up when someone measures what a visitor’s browser actually does, not what a plugin reports about itself. If your own site’s speed score looks fine but you have not checked what a real visitor’s connection actually downloads, that gap is worth closing before it costs you the way it was costing this one.
Want to know what your own site is really doing? Our free Uh Oh Score scanner checks for exactly this kind of gap, no strings attached.
If you want to see a similar audit on a different kind of site, our reCAPTCHA vs Turnstile case study found a different invisible tax hiding behind a working setup.
Not sure what your own site’s dashboard isn’t telling you? Talk to a WordPress expert and find out.
Talk to a WordPress ExpertFrequently Asked Questions
What does WordPress image optimization actually mean, and how do I know if it is working?
Real WordPress image optimization means a visitor’s browser actually receives a smaller file, not just that a smaller file exists somewhere on your server. The only reliable way to check is to open your browser’s developer tools, load a page, and look at the actual file type and size being downloaded for each image, not the plugin’s own dashboard summary.
How can a caching plugin’s preload feature end up hurting a site instead of helping it?
Preload is meant to warm the cache by visiting every page before a real visitor does, which usually helps. It becomes harmful when the crawl schedule and the cache-clearing schedule fight each other, so the crawl never finishes before it has to start over. On a small site this rarely matters. On a large, frequently updated site, it can become the single biggest source of server load.
Why did fixing image delivery break lazy loading, and how do I avoid that?
Some image optimization plugins alter the page’s HTML markup directly to deliver modern formats, and that markup change can conflict with a separate caching or lazy-loading plugin’s own script. The safer approach is a server-level image delivery method that serves the modern format based on what the visitor’s browser supports, without touching the page markup at all.
How do I check if my own site is generating traffic against itself?
Pull your server’s access logs and look for requests coming from your own server’s IP address at a regular, mechanical interval. A real visitor’s traffic looks irregular. A misconfigured crawl looks like a metronome.
Does putting a site behind Cloudflare fix this kind of problem automatically?
No. Cloudflare can stop external crawler traffic from reaching your server and can cache pages at the edge, which helps a great deal, but it will not fix a caching plugin’s own preload setting fighting itself, or an image optimizer that is not actually delivering its files. Those need to be fixed directly.
Why did not a plugin scan or the site’s own speed score catch any of this?
Because every individual tool was reporting on itself accurately. The optimizer really had generated the files. The caching plugin really was running its preload feature. Nothing was lying. The problem only exists when you look at what a real visitor’s browser actually receives, which no single plugin’s dashboard measures.
Can this happen on a smaller WordPress site, or is this specific to sites this large?
The individual causes, an unfinished optimizer setting and a preload schedule that never finishes, can happen on a site of any size. The scale of the damage is what changes. A small site with a few hundred pages might waste a modest amount of server time. A 15,000-page site running the same misconfiguration turns it into 40 percent of all traffic.
How long did it take to find and fix all three problems?
Finding the self-crawl took the longest, since it required reading 79 days of raw server logs rather than anything a dashboard could show directly. Once identified, all three fixes, the crawl loop, the image delivery, and the lazy-loading conflict, were implemented and verified within the same engagement.
What is the difference between an image being optimized and an image being delivered?
Optimized means a smaller, modern-format version of the file exists somewhere on the server. Delivered means that version is what actually gets sent to a visitor’s browser. A plugin can do the first perfectly and still fail completely at the second, which is exactly what happened here for months without anyone knowing.
Should I turn off my caching plugin’s preload feature entirely?
Not necessarily. Preload is genuinely useful on most sites, warming the cache so the first real visitor to a page does not wait for it to generate. The fix here was not disabling it forever, it was making sure the crawl schedule and the cache-clearing schedule do not fight each other, which is worth checking on any site using both features together.
Why does a caching plugin need a preload feature at all?
Preload exists so the first visitor to a page after the cache clears does not have to wait for WordPress to generate that page from scratch. The plugin visits every page itself right after clearing the cache, so a cached version is already sitting ready before a real visitor arrives. It is a genuinely useful feature, when the crawl schedule and the cache lifetime are set to work with each other instead of against each other.
Is this the same thing as a DDoS attack?
No, and that distinction matters. A DDoS attack is traffic sent deliberately by someone else to overwhelm a server. This was the opposite: traffic the site’s own software generated against itself, by accident, because two settings inside the same WordPress install were never configured to work together. No attacker was involved anywhere in this case.
Does this kind of problem affect SEO rankings, not just visitor experience?
Yes. Page speed and Core Web Vitals are direct ranking factors, and a homepage sending 5.4MB to every visitor works against both. The self-inflicted crawl traffic adds a second, indirect cost too: real search engine crawlers are competing for server resources against a server that is busy crawling itself, which can slow down how quickly new content gets indexed.