Performance Testing for Magento E-Commerce Sites
Load test a Magento store's category, cart and checkout flows under Black Friday traffic from 25+ regions. Find the user ceiling before the sale.
Load test a Magento store the way a sale hits it
A Magento store rarely fails on the home page. It fails on layered navigation with a cold full-page cache, on the cart when sessions pile up in Redis, and on checkout when every step writes to MySQL. This template mixes those pages in the proportions a real sale produces, ramps to a peak, and holds it long enough for the cache to churn and the database to fall behind.
Configuration
| Setting | Value | Why |
|---|---|---|
| Virtual users | 800 | Roughly a mid-size store’s Black Friday peak; scale to your analytics. |
| Duration | 20 minutes | Long enough for full-page-cache expiry and cron jobs (indexers, order emails) to overlap with traffic. |
| Ramp-up | 240 s in 8 steps | 100 users every 30 seconds; watch the cart and checkout requests separately at each step. |
| Request mix | 50% category and search, 30% product, 15% add to cart, 5% checkout | Typical conversion funnel; the 5% is what breaks. |
| Sessions | One session per virtual user, cookies kept | Cart and checkout depend on the session cookie; without it you are only testing the cache. |
| Think time | 3 to 8 s | Shoppers read product pages; checkout steps take longer. |
Run this templateOpens the cloud test form with these values filled in. Free plan runs it at the free user limit; sign in or create a free account first.
The button prefills users, duration and ramp-up. Add the store URLs (a category page with filters, a product, the cart endpoint and the checkout steps), keep cookies on, and start. For the checkout steps use a staging store or a test payment method.
What to read in the results
- Category and search pages first. These are the full-page-cache test. If they slow down with users, Varnish or the built-in cache is missing (check the X-Magento-Cache-Debug header in the response) or layered navigation is hitting Elasticsearch on every request.
- Cart and checkout separately. Filter the results by request. Add-to-cart writes the quote; checkout writes orders, inventory and payments. A p95 on checkout three times the category p95 is normal; ten times means MySQL locks or a slow payment sandbox.
- Errors by status code. 503 from the cache layer at the top of the ramp is PHP-FPM out of workers. 500 on checkout only is usually inventory reservation or a third-party (tax, shipping, payment) call timing out.
Pass/fail thresholds for this template
| Threshold | Target | What a breach means |
|---|---|---|
| p95 response time | < 1,500 ms | Product and category pages feel slow at the sale peak. |
| Error rate | < 0.5% | Orders are failing; every one is a lost sale. |
| Throughput | > peak page views per second from last year | The store cannot serve last year’s peak, let alone growth. |
Set them on the test and the sale readiness question becomes a green or red run in the Trend tab, per release.
The same scenario as a k6 script
As a k6 script the funnel is explicit: category, product, cart, and one checkout in twenty iterations. Replace the paths and the product id with yours.
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [{ duration: '4m', target: 800 }, { duration: '16m', target: 800 }],
thresholds: { http_req_duration: ['p(95)<1500'], http_req_failed: ['rate<0.005'] },
};
const BASE = 'https://store.example.com';
const jar = http.cookieJar();
export default function () {
check(http.get(`${BASE}/women/tops-women.html?color=50&size=166`), { 'category 200': (r) => r.status === 200 });
sleep(3 + Math.random() * 5);
check(http.get(`${BASE}/radiant-tee.html`), { 'product 200': (r) => r.status === 200 });
sleep(3 + Math.random() * 5);
if (Math.random() < 0.3) {
const add = http.post(`${BASE}/checkout/cart/add/product/1556/`, { qty: 1, product: 1556 });
check(add, { 'add to cart ok': (r) => r.status === 200 || r.status === 302 });
sleep(5);
if (Math.random() < 0.17) check(http.get(`${BASE}/checkout/`), { 'checkout 200': (r) => r.status === 200 });
}
}When to run it
- Four weeks before a sale so there is time to act on the numbers.
- After every Magento upgrade or extension install extensions are the usual source of a new slow query.
- After changing hosting, PHP-FPM or Redis sizing to confirm the change did what the invoice says.
FAQ on Magento load testing
Should I test production or staging?
Category and product pages can be tested on production at a quiet hour with the cache warm. Cart and checkout write data: use staging or a production store with test products and a sandbox payment method.
How do I keep the test from placing real orders?
Stop the flow at the checkout page (no payment submission), or point the checkout step at a payment sandbox. The template above only loads the checkout page.
The category pages are fast but the ramp shows errors at 600 users.
Look at which request fails. If it is add-to-cart, PHP-FPM is out of workers for uncached requests; the cache hides the shortage until the write path exposes it.
Does this work for Adobe Commerce Cloud?
Yes. The same requests apply; Fastly in front changes the cache headers to read (Fastly-Debug) but not the test.
How fast is your website?
Elevate its speed and SEO seamlessly with our Free Speed Test.Outgrown your testing tools?
Load test websites and APIs from 25+ cloud regions, monitor page speed and uptime, and get AI analysis that explains your results in plain English.Start for free→