MEASURED, NOT ESTIMATED

What a WooCommerce shop's
performance actually looks like.

There is no public baseline for this. Everyone asks "is 400 ms bad?" and gets an opinion back. Below are the numbers from five production WooCommerce shops over 24 hours — 80,657 requests — so you have something to compare your own against.

What this data is. Traffic recorded from working WooCommerce shops and replayed onto a public read-only account, with site names removed and every SQL value stripped before storage. It is real traffic, not synthetic load, and it is not five shops serving customers at this second. Every number here was pulled from our public endpoint when this page was built (2026-09-23) — you can query the same endpoint yourself, with no account: claude mcp add --transport http phpray https://phpray.dev/mcp

Measure your own shop Or read a full report first

Both free, both without an account. The rest of this page is the data.

Five shops, 24 hours

ShopRequests / 24 hp95FailedDatabase share
sklep-demo.pl30 894170 ms3.0%11%
sklep-nowy-demo.pl10 988233 ms5.6%8%
sklep-b2b-demo.pl12 207118 ms1.2%15%
blog-demo.pl16 88555 ms0.3%32%
klient-demo.pl9 68373 ms0.4%24%

Two things surprise people here. First, p95 varies four-fold between shops running the same software — 55 ms on a content site against 235 ms on a young shop. Second, the database is not where the time goes: it is 8–32% of wall time, and the busiest shop sits at the low end. The time is in PHP.

Which plugin spends it

From the busiest shop, self time per profiled request — that is time spent inside that plugin's own code, not in what it calls:

Plugin or themeSelf time per profiled request
plugins/woocommerce37.29 ms
themes/storefront24.57 ms
plugins/elementor7.39 ms
plugins/wordpress-seo6.14 ms
plugins/wpforms-lite5.06 ms
plugins/advanced-custom-fields6.51 ms
plugins/wordfence6.71 ms
plugins/really-simple-ssl2.86 ms

WooCommerce itself is the single largest cost and there is no way around that; it is the shop. What is worth looking at is everything below it. A security plugin at 6.51 ms on every request is a decision, not a fact of nature.

The queries that cost the most

Ordered by total time — average times call count — because that is what the database actually pays, not the single slowest query:

Total in 24 hCallsQuery (values masked)
2.1 s5020SELECT option_name, option_value FROM wp_options WHERE autoload IN (?)
1.8 s7794SELECT option_name, option_value FROM wp_options WHERE option_name IN (?)
1.8 s8618SELECT DISTINCT t.term_id, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id I
1.5 s5836SELECT option_value FROM wp_options WHERE option_name = ? LIMIT ?
1.5 s389UPDATE `wp_options` SET `option_value` = ? WHERE `option_name` = ?
1.2 s4214SELECT wp_comments.comment_ID FROM wp_comments JOIN wp_posts ON wp_posts.ID = wp_comments.comment_post_ID LEFT JOIN wp_p

Notice the shape: nothing here is slow. Every one of these is a fraction of a millisecond. They cost because they run thousands of times. Optimising the "slowest query" on such a shop finds nothing; the cost is in volume.

The part nobody sees

The busiest shop returned 3.0% 5xx responses in 24 hours. Here is the uncomfortable detail:

100 failed requests, showing 5. NONE of them raised a PHP error — these are 5xx responses, so the cause is outside PHP's error handler (a fatal before the handler, a timeout, the web server, or an upstream). Open one with phpray_trace to see the queries and outbound calls it made.

None of them raised a PHP error. They are invisible to error_log, to any tool that watches PHP's error handler, and to the shop owner — who only finds out when a customer writes in. They show up on product pages and on the home page, which means they cost orders.

How to compare your own shop

Three numbers are enough to know where you stand: p95, the share of 5xx, and self time of your three biggest plugins. If your p95 is under 200 ms and your 5xx share is under 1%, you are doing better than three of the five shops above.

Measure yours the same way

The local core is Apache-2.0, free without limits, and installs without root — including on shared hosting. On WordPress there is a plugin that needs neither an extension nor a daemon.

Install in one line See a full report first

Read next