A small online shop for workwear on WooCommerce, 52 products, taken over from a previous provider
Challenge
According to the owner the problem had lasted for months before the shop came to us: the server permanently at 100 percent, pages that loaded very slowly, and intermittent errors because the server did not answer in time. Standard measures had been tried and had changed nothing.
One hour of logs told the story. Of 172 057 requests, 68 110 went to a single category address with filter parameters, in 68 238 different combinations of colour and size. They came from 57 622 different addresses, most of which sent between one and five requests: home internet connections in many countries, routed through a commercial network of residential proxies. The browser signature was forged, and the estimated transfer of about 90 GB a day meant someone was paying for the operation.
Solution
First the measurement: what one request of each kind costs the server. A static file 0.65 milliseconds, any request to WordPress 90 to 120 milliseconds, a filtered product list 257 milliseconds. The static files were the bulk of the requests and 0.4 percent of the cost; the filter requests were the whole load.
Then a rule at the edge of the network: the firewall in front of the shop rejects the bot traffic in its earliest phase, before a request reaches WordPress. Rejecting a request costs about a millisecond; rendering a list costs 257. We recognise the traffic by how it moves through the shop, not by where it comes from. When the bots adapted a month later, a second rule based on the navigation behaviour of a real browser was in place minutes after the diagnosis. Every change was checked against real customers: filtering, search, cart, checkout and visits from search engines work as before.
Results
- Shop server
- From 926 % to 16 % of CPU after the first rule
- Shop server after the bots adapted
- From 905 % to 1 % within two minutes of the second rule
- Database server
- From 123 % to 0.01 % of CPU
- Filter requests reaching the shop
- From 68 110 an hour to a few hundred, all from people
- Requests rejected at the edge
- About 90 a second
- Changes customers noticed
- None: filters, search, cart and search-engine visits unchanged