If your WooCommerce store feels slow and your resource usage keeps creeping up with no sales to show for it, bots are almost certainly the reason. Automated traffic now makes up more than half of all web requests, and a big share of it targets the most expensive pages you have: add-to-cart, checkout, and search. Kinsta recently logged bots hitting add-to-cart URLs 7.67 million times on a single set of sites.
The fix is not one magic setting. It's a short stack of blocks: stop the cheap junk at the edge, throttle the requests that reach PHP, and make your cart endpoints boring targets. You can do most of it today without touching a real shopper's experience.
Why add-to-cart hits cost you more than a normal page view
Every add-to-cart request forces WooCommerce to build a session, write to the database, and skip your cache entirely — so it's one of the most expensive requests your store can serve.
A normal product page can be served from a cache in a few milliseconds without ever waking PHP or MySQL. An add-to-cart hit is the opposite. WooCommerce spins up a session, touches wp_options or wp_actionscheduler, writes cart data, and returns an uncached response. Multiply one expensive request by a few hundred thousand daily bot hits and you get the pattern most store owners actually feel: CPU spikes at random hours, a database that's always busy, and a slow admin dashboard while your homepage looks fine.
The bandwidth side is smaller but real. Bots crawling variable products pull down images and AJAX fragments over and over. The bigger bill is compute: PHP workers tied up on phantom carts are workers not available to the person about to check out.
How to tell bot cart traffic from real shoppers
You can spot bot cart traffic by looking for add-to-cart requests with no matching browsing session, no cookies, and a conversion rate near zero.
Open your access logs or your analytics and pull the ratio of add-to-cart events to actual orders. A healthy store adds to cart maybe 5–15 times per order. Work it through: if you took 40 orders yesterday, expect somewhere between 200 and 600 add-to-cart events. If your logs show 25,000, that's roughly 24,500 hits with no buyer attached — the gap is bots, not a good day for browsing. A few more tells:
- Requests straight to
?add-to-cart=123with no prior product page view in the same session. - Datacentre IP ranges — AWS, Hetzner, DigitalOcean, OVH — hammering the same endpoints. Real shoppers come from residential and mobile networks.
- Missing or identical user agents, or old browser strings like Chrome 90 showing up in 2025.
- No cookie support — the bot never carries a session forward, so every hit creates a fresh session row.
Grep is your friend here. On a Linux host, this pulls your top add-to-cart offenders:
grep "add-to-cart=" access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
If one IP or subnet shows tens of thousands of hits, you've found your problem and your first block.
Block the junk at the edge before it reaches PHP
The cheapest request to handle is the one your server rejects before WordPress ever loads, so your first line of defence belongs at the CDN or web-server level.
Cloudflare's free plan handles a lot of this. Create a rule that challenges or blocks requests to your cart and checkout paths that come from known bot ASNs or hosting providers. In a Cloudflare WAF custom rule, an expression like (http.request.uri.path contains "/cart/" and ip.geoip.asnum in {16509 24940 14061 16276}) matches cart traffic from AWS, Hetzner, DigitalOcean and OVH respectively — set the action to Managed Challenge so a real browser passes it silently. Also add a rate-limiting rule of, say, 10 requests per minute to add-to-cart URLs per IP, and turn on Bot Fight Mode.
Prefer to stay at the server? Nginx can throttle the same paths:
limit_req_zone $binary_remote_addr zone=cart:10m rate=5r/m;
Then apply limit_req zone=cart burst=5 nodelay; inside a location block matching your cart endpoint. On Apache, a few mod_rewrite rules blocking empty or blacklisted user agents on cart requests cut a surprising amount of noise. The point is the same across all of them: reject cheaply, and never let a scraper wake up MySQL.
WooCommerce-side blocks that don't hurt real buyers
Inside WooCommerce, the goal is to make cart endpoints harder to hammer without adding friction for someone who's actually shopping.
Start with these settings and add-ons, in rough order of payoff:
- Enable AJAX add-to-cart and disable the redirect to the cart page. Direct
?add-to-cart=GET links are trivially scriptable; the AJAX flow needs a nonce, which most dumb bots don't send. - Require a valid nonce on cart actions and reject requests without one. Many bots replay a stale link forever — a rotating nonce breaks the replay.
- Add a honeypot or lightweight challenge at checkout. Plugins like WooCommerce Anti-Fraud or a hidden form field catch bulk carding attempts without a visible CAPTCHA.
- Clear stale sessions aggressively. WooCommerce ships a WP-Cron event named
woocommerce_cleanup_sessionsthat runs twice daily and clears expired rows fromwp_woocommerce_sessions; expired transients are handled separately by thedelete_expired_transientsevent onwp_options. Under a bot flood the twice-daily cadence lags behind, so trim the table by hand:wp db query "DELETE FROM wp_woocommerce_sessions WHERE session_expiry < UNIX_TIMESTAMP();". Confirm the cron is even scheduled withwp cron event list, since a broken WP-Cron lets sessions pile up unnoticed. - Rate-limit the WooCommerce Store API. The newer block-based cart uses
/wp-json/wc/store/cart— bots have found it too, so throttle it the same as the classic endpoint.
One caution: don't slap a CAPTCHA on your add-to-cart button. It kills conversions. Keep challenges invisible until behaviour looks abusive, and reserve any visible check for checkout, where the stakes are higher and the friction is expected.
A quick comparison: where to put each block
The right layer depends on how expensive the request is to serve — push the cheapest rejections furthest from your database.
| Layer | Blocks | Best for |
|---|---|---|
| CDN / Cloudflare | Known bot ASNs, rate limits, bad user agents | High-volume junk, cheapest to run |
| Web server (Nginx/Apache) | Per-IP rate limits, empty user agents | Fine-grained control without a CDN |
| WooCommerce | Nonces, honeypots, session cleanup | Bots that pass the edge |
| Database hygiene | Expired sessions and transients | Cleaning up what got through |
Stack them and each layer only handles what the one before it missed. That's what keeps your PHP workers free for real checkouts.
Where your hosting fits in
Good hosting won't stop bots for you, but it decides whether a bot wave slows your store to a crawl or barely registers — so pick a host that gives you the tools and the humans to act on them.
On shared plans especially, bot cart traffic eats the CPU and memory your real shoppers need. If your host is vague about resource limits or leaves you alone with a spiking dashboard, that's a problem. At TPC Hosting you get real engineers on support around the clock who'll help you read the logs and set up the right blocks, plus EU hosting that keeps your customer data GDPR-friendly. If you're moving from a host that couldn't cope, our free migration gets you across without downtime, and you've got 30 days to back out if it isn't the right fit.
The short version: measure your add-to-cart-to-order ratio, block the cheap junk at the edge, add nonces and session cleanup in WooCommerce, and keep an eye on the logs. Do that and the phantom carts stop costing you money — and your store gets fast for the people who actually buy.
FAQ
How do I know if bots are hitting my add-to-cart URLs?
Compare your add-to-cart events to actual orders — if you're seeing thousands of cart hits and only a handful of sales, that gap is almost entirely bots. Then grep your access logs for 'add-to-cart=' and count hits per IP; a single address with tens of thousands of requests is a bot you can block immediately.
Will blocking cart bots slow down real customers?
No, if you use invisible challenges and rate limits rather than a visible CAPTCHA on the add-to-cart button. Real browsers pass Cloudflare managed challenges and WooCommerce nonce checks silently, while scripts that skip cookies and nonces get stopped — so genuine shoppers never notice.
Why are add-to-cart hits so expensive compared to normal pages?
Add-to-cart requests can't be cached because they create a session and write cart data to your database. A normal product page serves from cache in milliseconds, but every cart hit wakes up PHP and MySQL, so a flood of them ties up the workers your real buyers need.
Should I use Cloudflare or server-side rules to block cart bots?
Use both, layered — Cloudflare's free plan handles high-volume junk cheaply at the edge, while server-side rate limits in Nginx or Apache catch what gets through. Push the cheapest rejections furthest from your database, then let WooCommerce nonces mop up the rest.
How do I clean up the bot carts already sitting in my database?
WooCommerce's 'woocommerce_cleanup_sessions' WP-Cron event clears expired rows from wp_woocommerce_sessions twice a day, but under a bot flood that lags behind. Trim the table by hand with a WP-CLI query deleting rows where session_expiry is in the past, and check the cron is actually scheduled with 'wp cron event list'.

