Hi again @pdjp 🙂
Very good question, again, and the Wordfence comparison is exactly the root of the confusion, so let me clear that up.
The numbers aren’t comparable. Vigilant’s rate limit counts only PHP requests that load WordPress (pages, admin-ajax.php, REST API, wp-login.php) from a single IP. It does not count the static assets you see in your browser’s Network tab (CSS, JS, fonts, images), because your web server delivers those without booting WordPress. A page that shows 80 requests in the browser usually counts as just 1–2 against the rate limit. Wordfence’s 480/960/1920 count differently (and segment humans vs crawlers vs 404s), so matching the raw number is misleading. Their “unlimited” is really “rate limiting off”.
Why you’re getting blocked at 120/min: that almost always means a plugin is loading content through PHP on the fly, via admin-ajax.php or the REST API. If your image plugin pipes each thumbnail through PHP instead of serving a direct URL, one page load can rack up dozens of PHP hits. That’s the first thing to check.
About the 500 max: it isn’t an arbitrary cap, it’s a deliberate ceiling. 500 PHP requests per minute from a single IP is a lot. Normal human traffic never reaches it; whatever does is usually a bot, which is exactly what the rate limit is meant to catch.
So instead of disabling rate limiting (which leaves you with no protection at all), I’d suggest:
- See whether that image plugin can serve images as direct URLs / static files instead of through PHP. That fixes the cause.
- If it can’t, raise the limit to 240–480 rather than turning it off. That still protects you while giving the plugin room.
- If it’s only you or a known service hitting the cap, whitelist that IP in the firewall settings (logged-in admins are already exempt automatically).
Good overall values: 120/min is fine for most sites; WooCommerce / membership / AJAX-heavy sites are comfortable at 240–480.
One thing your question made clear: the setting doesn’t explain any of this in the UI. I’ll add a short description to that field in the next release so it’s obvious what counts as a request. Thanks for the feedback 😉
Thread Starter
pdjp
(@pdjp)
Thx for the explanation, only PHP requests makes sense. 🙂
The suspicious function is not a normal WP plugin, it’s the Pano2VR player, which loads tons of images and additional product information from the normal WP posts via iframe. I don’t know how it works, but the complaining people were all using that function before it happened.
Thanks, that’s the missing piece, Pano2VR explains it perfectly.
Vigilant’s rate limit only counts requests that boot WordPress (PHP). Pano2VR creates two very different kinds of load:
- The panorama tiles (the “tons of images”) are normally static
.jpg files served straight from /wp-content/uploads/. Your web server delivers those without loading WordPress, so they don’t count toward the limit.
- The iframes pulling product info from your WP posts are the real cause: each one is a full WordPress page load, so it does count. A tour with 30–50 hotspots opening iframes to posts can fire 30–50 PHP hits in a single viewing session, all from one visitor’s IP. That’s why only the people using the tour got blocked — they weren’t abusing anything, the tour just makes a lot of genuine WordPress requests per visit.
Because those visitors come from many different IPs, whitelisting won’t help here. The right move is to give the limit more room rather than switch it off (turning it off removes the protection completely):
Try raising “Requests per Minute” to 300 (and to 480 if needed) then re-test the tour. A real attacking bot still blows past those numbers, so you stay protected while letting a normal tour session through.
To find the right value, open the tour with your browser’s DevTools > Network tab and watch the requests. The .jpg files under /uploads/ are static and don’t matter; the ones that load WordPress (posts, REST, admin-ajax) are what count. Tally how many a normal session makes and set your limit comfortably above that.
If raising the limit still isn’t enough, there’s a more surgical option, a small code snippet that exempts only the tour’s URLs while keeping the strict limit everywhere else. Try the higher limit first, and if it doesn’t do it, let me know and I’ll send it over.