
A website stress test pushes your store past its normal traffic until response times climb or errors appear, so you learn where it breaks before shoppers find out for you. For an online store, the useful version tests the pages that make money (category, product, cart, checkout) against a staging copy or a scheduled window, ramps load up in stages, and stops short of calling your live payment provider.
Black Friday falls on 27 November 2026 and Cyber Monday on 30 November. As of mid-October that leaves about six weeks, which matters for two reasons covered below: Stripe asks for six weeks' notice on large rate-limit increases, and Shopify asks headless (Hydrogen) merchants to book load tests three to five weeks ahead. If you start this week, you still have time to run a test, fix what it finds, and test again before your code freeze.
Three dated constraints make mid-October the practical start line.
Stripe's rate-limit documentation (checked October 2026) sets a global limit of 100 API requests per second in live mode and 25 in a sandbox, with most individual endpoints at 25 per second. The same page advises against load testing through the sandbox, because the lower limits trigger throttling you would never see in production and because sandbox payments are simulated, so latency differs. Stripe recommends building a configurable mock of its API that waits for a delay sampled from your real live-mode call times. If you expect a flash-sale burst to approach the limits, Stripe asks you to contact support, and for a large increase, to do so at least six weeks in advance. Counting back from 27 November, six weeks lands on 16 October 2026.
Shopify's Hydrogen production checklist warns that its anti-bot system may treat a load test as bot traffic and throttle it, and asks you to coordinate a scheduled test with your Merchant Success Manager or Shopify Support three to five weeks before go-live. That guidance is written for headless Hydrogen builds. For a standard Shopify theme store, the platform runs the infrastructure, so your stress test effort belongs on the parts you control: custom apps, middleware, ERP and inventory integrations.
If you host on AWS, the EC2 testing policy allows stress tests (it names them "stress tests, load tests, or gameday tests") within its conditions, and it prohibits volumetric network DDoS simulations from EC2. Other hosts and CDNs have their own rules. Read yours before you send traffic, because a WAF or rate limiter that blocks your test generator tells you nothing about real shoppers.
| Signal | Who owns it | What to check | How often during the test |
|---|---|---|---|
| Error rate (HTTP 5xx, timeouts) | Developer or agency | Share of failed requests per step of the journey | Continuously; abort above your threshold |
| Response time, 95th percentile | Developer or agency | Product, cart and checkout pages separately | Continuously |
| Database load and slow queries | Host or developer | Slow query log, connection count, locks | Every few minutes |
| PHP workers or app instances | Host | Busy versus available workers, queue length | Every few minutes |
| Cache hit ratio | Developer or CDN owner | Hit rate on category and product pages | At each load stage |
| Background jobs | Developer | Queue depth (for WooCommerce, Action Scheduler pending actions) | Before, during and after |
| External uptime from several regions | Store owner or agency | Homepage and checkout URL respond from outside your network | Every minute |
The script below browses the store and adds to cart. It does not submit payment. Replace the URLs with your own pages, and run it against staging first.
import http from 'k6/http';
import { check, sleep } from 'k6';
const BASE = __ENV.BASE_URL || 'https://staging.example-store.com';
export const options = {
stages: [
{ duration: '10m', target: 50 }, // ramp to expected peak (illustrative)
{ duration: '20m', target: 50 }, // hold at expected peak
{ duration: '10m', target: 100 }, // ramp past peak: the stress part
{ duration: '20m', target: 100 }, // hold above peak
{ duration: '5m', target: 0 }, // ramp down
],
thresholds: {
http_req_failed: ['rate<0.01'],
'http_req_duration{page:product}': ['p(95)<1500'],
'http_req_duration{page:cart}': ['p(95)<2000'],
},
};
export default function () {
let res = http.get(`${BASE}/shop/`, { tags: { page: 'category' } });
check(res, { 'category 200': (r) => r.status === 200 });
sleep(Math.random() * 3 + 2);
res = http.get(`${BASE}/product/sample-product/`, { tags: { page: 'product' } });
check(res, { 'product 200': (r) => r.status === 200 });
sleep(Math.random() * 3 + 2);
res = http.get(`${BASE}/cart/?add-to-cart=123`, { tags: { page: 'cart' } });
check(res, { 'cart 200': (r) => r.status === 200 });
sleep(Math.random() * 5 + 3);
}
The add-to-cart query string works on a default WooCommerce install; other platforms need their own cart call. Virtual users and requests per second are different units, so compare the k6 summary against your analytics baseline rather than reading the target numbers as visitors.
Test plan to paste into your ticket or shared document:
STRESS TEST PLAN - <store name> - <date>
Target: staging / production window <start-end, timezone>
Journeys: category, product, add to cart, checkout to payment page
Payment: mocked / stopped before payment step (no live or sandbox API calls)
Side effects disabled: order emails, ERP push, marketing pixels, webhooks
Notified: host <name>, CDN/WAF <name>, on-call <name>
Load generator IPs: <list>
Stages: smoke -> average load (<N> VUs) -> stress (<N> VUs) -> optional spike
Abort if: error rate > <x>% for 2 minutes, or database CPU > <y>% for 5 minutes
Owner who can stop the test: <name, phone>
Results file: <link>
Re-test date: <date>
A WooCommerce store recorded about 1,200 sessions in its busiest hour last November. The agency builds the script above, sets the hold stage at 50 virtual users to approximate that hour, and runs it on a staging server cloned the night before.
The average-load run passes. During the stress stage at 100 users, product pages stay under a second, but the cart step's 95th-percentile time climbs past six seconds and the error rate hits 4%. The slow query log shows a shipping-rate plugin calling an external API on every cart load. The developer caches the rate response for a few minutes, raises the PHP worker count after checking memory headroom with the host, and reruns the same script two days later. The cart step holds at under two seconds at 100 users. The store then enters its code freeze with a known ceiling and a record of what changed.
The numbers here are invented for illustration. Your thresholds should come from your own baseline.
A stress test has limits of its own. Synthetic users do not behave like real shoppers, the generator itself can become the bottleneck, and staging seldom matches production in every detail. Third-party services such as payment, tax, shipping and reviews will behave differently under real peak traffic. A passing test lowers the odds of a Black Friday website crash; it gives no guarantee, and you still need monitoring and an incident plan for the day itself. Our peak sales readiness plan covers the wider preparation, and the Black Friday code freeze guide covers what to lock after testing.
In k6's definitions, an average-load test checks behaviour under expected normal conditions, and a stress test checks behaviour when load exceeds that average. Run the load test first; a stress test on a site that already fails at normal load tells you little.
On a standard theme store, Shopify runs the infrastructure, so focus your testing on your custom apps and integrations. For a headless Hydrogen storefront, Shopify's production checklist says its anti-bot system may throttle load tests and asks you to coordinate with Shopify Support or your Merchant Success Manager three to five weeks ahead.
Staging is safer. If staging cannot match production, test production during an agreed low-traffic window, with the host informed, side effects disabled, payments stubbed, and one named person who can stop the test.
During the test window and on the peak days themselves, someone has to watch the store from outside. Pingvera runs one-minute uptime checks from several regions on every plan, including the free one. For WooCommerce stores, its connector sends order events, and anomaly detection compares order flow with an hourly baseline, so you get an alert when the site responds but orders stop. Deploys, incidents and order events appear on one timeline, which helps when a fix made after the stress test changes checkout behaviour. See also WooCommerce checkout monitoring and catching a store that stopped selling.
Last reviewed: 14 October 2026
Pingvera watches whether an online business actually works — uptime, checkout, orders, domain, SSL and server — and alerts you in Telegram, email or a webhook before a customer has to tell you.
Start freeRead next: Black Friday Code Freeze 2026: What to Lock and Still Patch · How to Test a Website Backup Restore · Marketplace and Store Reconciliation · How much to charge for website maintenance — and what to actually put… · Run a free site check.