---
title: Website Stress Test Before Black Friday — A Six-Week Plan for Online Stores
description: How to run a website stress test on your online store before Black Friday 2026 — test types, payment sandbox limits, a k6 script and a safe test plan.
source: https://pingvera.com/blog/website-stress-test-black-friday.html
---
# Website Stress Test Before Black Friday: A Six-Week Plan for Online Stores

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.

## At a glance

- Run a smoke test and an average-load test first. Grafana's k6 guidance says to run stress tests only after average-load tests pass.
- Test a staging copy that matches production, or production in an agreed low-traffic window with the host's knowledge.
- Do not load test against a payment provider's sandbox. Stripe's sandbox has a lower rate limit (25 requests per second against 100 in live mode) and simulated latency, so results mislead.
- On hosted platforms, coordinate first. Shopify's anti-bot system can throttle load-test traffic on Hydrogen storefronts.
- Watch backend signals during the test (database, PHP workers, queue depth, error rate) as well as page load time.
- Leave time for a second run. First runs tend to find something to fix.

## Why it matters now

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.

## Step-by-step: run a stress test you can trust

1. Pick the journeys. List the four or five paths that carry revenue: home or landing page, category with filters, product page, add to cart, checkout up to the payment step. Add site search if shoppers use it a lot.
2. Set your baseline from analytics. Find last year's busiest hour (or your busiest hour this year) in sessions and orders. That number becomes your "average-load" target for the peak period.
3. Choose the environment. A staging server with the same PHP or Node version, the same database size, the same caching layers and the same plugins is the safer choice. If staging is much smaller than production, results only show relative changes.
4. Stub the payment step. Point the payment gateway at a mock that returns success after a realistic delay, as Stripe recommends, or stop the scripted journey at the payment page. Disable outbound order emails, ERP pushes and marketing pixels on the test target, or route them to a sink.
5. Tell people. Notify the host, the CDN or WAF owner, and anyone on call, with the window and the source IPs of your load generator. Allowlist those IPs in the WAF only if you want to measure the origin; keep the WAF in place if you want to see how it behaves.
6. Run a smoke test. A handful of virtual users for a few minutes confirms the script works and the target responds.
7. Run an average-load test at your baseline from step 2 and record response times and error rate. Fix anything that fails here before going further.
8. Run the stress test. Ramp up in stages (k6 suggests ramp-ups of ten minutes or more for higher loads) to a level above your expected peak, hold it, then ramp down. k6's own guidance gives no fixed multiplier; pick one from your own risk, such as an email blast landing at the same time as a paid campaign.
9. Optionally run a spike test. k6 lists seasonal sales such as Black Friday as a typical case for sudden, short surges, and warns that errors are common in these tests.
10. Fix, then re-test. Typical fixes include page cache rules that exclude too much, uncached cart fragments, slow filter queries, too few PHP workers, and third-party scripts that block rendering. Run the same script again so the numbers compare.

## What to watch during the test

## Copyable artefact: k6 script and test plan

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>
`
Worked scenario (illustrative)
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.

## Common mistakes

- Load testing the payment provider's sandbox and treating the throttling as a real limit, which Stripe's documentation warns about.
- Testing a staging server with a tenth of production's database and concluding the live site is fine.
- Leaving order emails or ERP sync switched on, so the test creates fake orders downstream.
- Running the first test the week before Black Friday, with no time to fix or re-test.
- Hitting only the homepage, which is often the most cached page on the site.
- Letting the WAF block the load generator and reading the blocked requests as a capacity limit.

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](https://pingvera.com/blog/ecommerce-peak-sales-readiness.html) covers the wider preparation, and the [Black Friday code freeze guide](https://pingvera.com/blog/black-friday-code-freeze-security-patches.html) covers what to lock after testing.

## FAQ

### What is the difference between a website load test and a stress test?

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.

### Can I stress test a Shopify store?

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.

### Should I stress test production?

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.

## Where Pingvera fits

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](https://pingvera.com/blog/woocommerce-checkout-monitoring.html) and [catching a store that stopped selling](https://pingvera.com/blog/woocommerce-orders-stopped-anomaly-detection.html).

## Sources

- [Stripe: Rate limits (including load testing guidance)](https://docs.stripe.com/rate-limits)
- [Grafana k6: Load test types](https://grafana.com/docs/k6/latest/testing-guides/test-types/)
- [Grafana k6: Stress testing](https://grafana.com/docs/k6/latest/testing-guides/test-types/stress-testing/)
- [Grafana k6: Spike testing](https://grafana.com/docs/k6/latest/testing-guides/test-types/spike-testing/)
- [Shopify: Hydrogen production checklist](https://shopify.dev/docs/storefronts/headless/hydrogen/production-checklist)
- [AWS: Amazon EC2 testing policy](https://aws.amazon.com/ec2/testing/)

Last reviewed: 14 October 2026
