load-testing-commerce

Simulate realistic shopper traffic on your checkout and catalog pages using k6 or Artillery to find performance bottlenecks before launch

11 stars

Best use case

load-testing-commerce is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Simulate realistic shopper traffic on your checkout and catalog pages using k6 or Artillery to find performance bottlenecks before launch

Teams using load-testing-commerce should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/load-testing-commerce/SKILL.md --create-dirs "https://raw.githubusercontent.com/finsilabs/awesome-ecommerce-skills/main/skills/infrastructure-performance/load-testing-commerce/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/load-testing-commerce/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How load-testing-commerce Compares

Feature / Agentload-testing-commerceStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Simulate realistic shopper traffic on your checkout and catalog pages using k6 or Artillery to find performance bottlenecks before launch

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Load Testing — Commerce

## Overview

Load testing e-commerce applications requires more than hammering an endpoint with concurrent requests. Realistic test scenarios simulate actual user behavior: browsing the catalog, searching for products, adding items to a cart, and completing checkout — including the think time between actions. This skill covers building realistic shopping scenarios in k6 and Artillery, interpreting results to find bottlenecks, and establishing performance baselines before major sales events.

## When to Use This Skill

- When preparing for a flash sale, Black Friday, or seasonal traffic spike
- When deploying a major infrastructure change (new database, CDN, checkout service)
- When establishing performance SLOs and baselines for a new storefront
- When a production incident was caused by load and you need to reproduce it in staging
- When a new checkout feature is being released and its performance impact is unknown

## Core Instructions

### Step 1: Determine your platform and what you can test

| Platform | Load Testing Scope | Recommended Approach |
|----------|-------------------|---------------------|
| **Shopify** | Shopify's infrastructure scales automatically — you cannot overload it meaningfully | Test your theme's frontend performance with Google PageSpeed Insights and Lighthouse CI; test any custom apps or storefronts you host separately |
| **WooCommerce** | You own the server — load testing is critical before sales events | Use **Loader.io** (free tier: 1 target, 10K connections/test) against your staging site; or k6/Artillery for detailed scenario testing |
| **BigCommerce** | BigCommerce scales automatically — platform infrastructure is not a concern | Test your theme's frontend performance with PageSpeed Insights; test any custom middleware or headless layer you host |
| **Custom / Headless** | Full control — load testing is your responsibility | Use k6 (open-source, scriptable) or Artillery (YAML-based) with realistic shopping scenarios against a staging environment |

### Step 2: Platform-specific load testing

---

#### Shopify

Shopify's infrastructure handles virtually any traffic spike. Your load testing focus is the frontend experience:

1. **Run Google PageSpeed Insights** on your most critical pages (product page, collection page, checkout):
   - Go to [pagespeed.web.dev](https://pagespeed.web.dev) and test your product and collection pages
   - Target a Performance score of 75+ on mobile; address any red/orange recommendations before your sale

2. **Check Shopify's built-in performance report**:
   - Go to **Online Store → Themes** and click **View report**
   - This shows your store's Core Web Vitals (LCP, CLS, FID) based on real user data
   - A poor LCP score on mobile almost always means the hero image needs `fetchpriority="high"` or compression

3. **Audit your installed apps before a sale**:
   - Go to **Apps** in your Shopify admin and review every app injecting scripts into your storefront
   - Each third-party script adds 50–200ms; remove unused apps and disable any that load synchronously

4. **For Shopify Plus — notify Shopify support before major launches**:
   - Submit a flash sale notification through your Plus support channel at least 48 hours before the event
   - Shopify can pre-allocate resources and monitor your store during the event

---

#### WooCommerce

WooCommerce runs on your hosting infrastructure. Test against a staging environment that mirrors your production configuration (same PHP version, same MySQL version, same caching stack).

**Quick load test with Loader.io (no code required):**

1. Sign up at [loader.io](https://loader.io) (free tier: 1 target, 10K connections per test)
2. Click **New Test** and enter your staging URL
3. Configure a ramp test: start at 0 clients, ramp to your expected peak traffic over 60 seconds, hold for 120 seconds
4. Loader.io provides a verification token — add it to a page on your staging site to confirm ownership
5. Run the test against your **checkout page** specifically — product browse is usually cached; checkout hits the database

**Interpret results:**
- Response time under 3 seconds at peak: acceptable
- Error rate above 1%: investigate server logs for PHP fatal errors, database timeouts, or memory exhaustion
- If the server struggles at lower than expected traffic: upgrade your hosting tier or add Redis Object Cache before the sale

**Before your test, ensure your staging stack is properly configured:**
- Redis Object Cache is active (**Settings → Redis** — green status)
- WP Rocket page cache is enabled and has warmed the most-visited product pages
- You're testing against the same server size you'll run in production

---

#### Custom / Headless

For custom storefronts, use k6 or Artillery against a staging environment that mirrors production.

**Important before you start:**
- Always test against **staging**, never production
- Use test-mode payment tokens (Stripe: `tok_visa`) — never run load tests against real payment processors
- Tag test orders with a recognizable email domain (e.g., `@test-load.invalid`) so you can bulk-delete them after
- Reserve test products with unlimited inventory so the checkout scenario doesn't fail due to oversells

**k6 realistic shopping scenarios:**

k6 uses a `ramping-arrival-rate` executor to control requests per second (more realistic than VU-based approaches). Typical e-commerce traffic distribution: 60% browse, 25% product detail, 10% cart, 5% checkout.

```javascript
// k6/commerce-load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { SharedArray } from 'k6/data';

const BASE_URL = __ENV.BASE_URL || 'https://staging.mystore.com';

const products = new SharedArray('products', function() {
  return JSON.parse(open('./data/products.json')); // array of {id, defaultVariantId}
});

export const options = {
  scenarios: {
    catalog_browsing: {
      executor: 'ramping-arrival-rate',
      startRate: 0, timeUnit: '1s',
      preAllocatedVUs: 50, maxVUs: 200,
      stages: [
        { target: 60, duration: '2m' },  // Ramp up
        { target: 60, duration: '5m' },  // Steady state
        { target: 0,  duration: '1m' },  // Ramp down
      ],
      exec: 'catalogBrowsing',
    },
    checkout_flow: {
      executor: 'ramping-arrival-rate',
      startRate: 0, timeUnit: '1s',
      preAllocatedVUs: 10, maxVUs: 50,
      stages: [
        { target: 5, duration: '2m' },
        { target: 5, duration: '5m' },
        { target: 0, duration: '1m' },
      ],
      exec: 'checkoutFlow',
    },
  },
  thresholds: {
    'http_req_duration{scenario:checkout_flow}': ['p(95)<3000'],
    'http_req_failed{scenario:checkout_flow}': ['rate<0.01'],
    'http_req_duration{scenario:catalog_browsing}': ['p(95)<1000'],
  },
};

export function catalogBrowsing() {
  http.get(`${BASE_URL}/api/collections/featured`, { tags: { step: 'homepage' } });
  sleep(2 + Math.random() * 3); // Think time: 2–5s

  const categories = ['t-shirts', 'hoodies', 'accessories'];
  const category = categories[Math.floor(Math.random() * categories.length)];
  http.get(`${BASE_URL}/api/collections/${category}?page=1&sort=popular`, { tags: { step: 'category' } });
  sleep(3 + Math.random() * 5);
}

export function checkoutFlow() {
  const product = products[Math.floor(Math.random() * products.length)];

  // View product
  const productRes = http.get(`${BASE_URL}/api/products/${product.id}`, { tags: { step: 'view_product' } });
  check(productRes, { 'product page 200': r => r.status === 200 });
  sleep(2 + Math.random() * 3);

  // Add to cart
  const cartRes = http.post(`${BASE_URL}/api/cart`, JSON.stringify({
    items: [{ productId: product.id, variantId: product.defaultVariantId, quantity: 1 }],
  }), { headers: { 'Content-Type': 'application/json' }, tags: { step: 'add_to_cart' } });
  check(cartRes, { 'add to cart 200': r => r.status === 200 });
  const cart = JSON.parse(cartRes.body);
  sleep(1 + Math.random() * 2);

  // Start checkout
  const checkoutRes = http.post(`${BASE_URL}/api/checkout/start`, JSON.stringify({
    cartId: cart.id,
    customer: { email: `test-${Math.random().toString(36).slice(7)}@test-load.invalid` },
  }), { headers: { 'Content-Type': 'application/json' }, tags: { step: 'start_checkout' } });
  check(checkoutRes, { 'checkout start 200': r => r.status === 200 });
  const checkout = JSON.parse(checkoutRes.body);
  sleep(5 + Math.random() * 10); // Think time: filling form

  // Place order
  const orderRes = http.post(`${BASE_URL}/api/checkout/complete`, JSON.stringify({
    checkoutId: checkout.id,
    paymentToken: 'tok_visa', // Stripe test token
    shippingMethodId: checkout.shippingMethods[0]?.id,
  }), { headers: { 'Content-Type': 'application/json' }, tags: { step: 'place_order' } });
  check(orderRes, { 'order placed 201': r => r.status === 201 });
}
```

**Artillery YAML config (alternative to k6 — good for API-focused testing):**

```yaml
# artillery/commerce-load-test.yml
config:
  target: "{{ $processEnvironment.BASE_URL }}"
  phases:
    - name: "Warm-up"
      duration: 60
      arrivalRate: 5
    - name: "Ramp up"
      duration: 120
      arrivalRate: 5
      rampTo: 50
    - name: "Peak load"
      duration: 300
      arrivalRate: 50
    - name: "Spike"
      duration: 30
      arrivalRate: 200
    - name: "Recovery"
      duration: 60
      arrivalRate: 20
  processor: "./processors/commerce-helpers.js"

scenarios:
  - name: "Browse catalog"
    weight: 60
    flow:
      - get:
          url: "/api/collections/all?page=1"
          capture:
            json: "$.products[0].id"
            as: "productId"
      - think: 3
      - get:
          url: "/api/products/{{ productId }}"

  - name: "Complete checkout"
    weight: 10
    flow:
      - function: "generateCheckoutData"
      - post:
          url: "/api/cart"
          json:
            productId: "{{ productId }}"
            quantity: 1
          capture:
            json: "$.id"
            as: "cartId"
      - think: 8
      - post:
          url: "/api/checkout/start"
          json:
            cartId: "{{ cartId }}"
            email: "{{ email }}"
          capture:
            json: "$.checkoutId"
            as: "checkoutId"
      - think: 10
      - post:
          url: "/api/checkout/complete"
          json:
            checkoutId: "{{ checkoutId }}"
            paymentToken: "tok_visa"
          expect:
            - statusCode: 201
```

**Run the test and capture a baseline:**

```bash
k6 run \
  --env BASE_URL=https://staging.mystore.com \
  --out json=results/baseline-$(date +%Y%m%d).json \
  k6/commerce-load-test.js
```

**Analyze results per step using tags:**

```bash
# Overall summary (k6 outputs this automatically at end of run)
# Per-step breakdown from the JSON output
cat results/baseline-*.json | jq '
  [.data_points[] | select(.type=="Point" and .metric=="http_req_duration")]
  | group_by(.tags.step)
  | map({step: .[0].tags.step, p95_ms: (map(.value) | sort | .[length * 0.95 | floor])})
'
```

**Scale targets for e-commerce:**
- Catalog pages p95 < 1000ms
- Product detail p95 < 1500ms
- Checkout flow p95 < 3000ms
- Error rate < 1% at peak

**Run load tests in CI before major releases (GitHub Actions):**

```yaml
# .github/workflows/load-test.yml
name: Load Test (Pre-Release)
on:
  workflow_dispatch:
    inputs:
      target_url:
        description: 'Staging URL to test'
        required: true
        default: 'https://staging.mystore.com'

jobs:
  load-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install k6
        run: |
          curl -s https://dl.k6.io/key.gpg | sudo apt-key add -
          echo "deb https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
          sudo apt-get update && sudo apt-get install k6
      - name: Run load test
        env:
          BASE_URL: ${{ github.event.inputs.target_url }}
        run: k6 run --env BASE_URL=$BASE_URL --out json=results.json k6/commerce-load-test.js
      - uses: actions/upload-artifact@v4
        with:
          name: load-test-results
          path: results.json
```

## Best Practices

- **Simulate think time between steps** — real users pause between actions; removing think time creates an unrealistically high request rate that doesn't reflect production patterns
- **Use test-mode payment tokens** — always use Stripe's `tok_visa` or equivalent test tokens; never run load tests against real payment processors
- **Run against staging, not production** — load tests consume resources and can degrade service for real customers
- **Profile at 1.5×, 2×, and 3× expected peak** — run multiple tests at different load levels to find your system's inflection point before the actual sale
- **Monitor the database and cache during tests** — watch for connection pool exhaustion, Redis evictions, and lock wait times in your DB; application-tier throughput can look fine while the database is saturated
- **Tag test orders for easy cleanup** — use a consistent test email domain (`@test-load.invalid`) so you can bulk-delete test data after runs: `DELETE FROM orders WHERE email LIKE '%@test-load.invalid'`

## Common Pitfalls

| Problem | Solution |
|---------|----------|
| Checkout scenario fails because products are sold out | Reserve test products with unlimited inventory; use a separate `is_load_test_product` flag and filter them from real catalog pages |
| Loader.io test passes but production still slows down | Staging may not mirror production load — confirm Redis Object Cache is active, MySQL version matches, and the server size is the same |
| k6 VUs exhausted before reaching target RPS | Use `ramping-arrival-rate` executor (controls RPS) instead of `ramping-vus` (controls concurrent users); increase `preAllocatedVUs` and `maxVUs` |
| Alert noise during planned load tests | Add a load test flag to your monitoring system (Datadog tag, Grafana annotation) to suppress non-critical alerts during the scheduled test window |
| Results not reproducible between runs | Use a `SharedArray` with a fixed dataset file instead of Math.random() product generation; fix the test data set before the run |

## Related Skills

- @flash-sale-scaling
- @monitoring-alerting-commerce
- @database-optimization-commerce
- @bot-protection

Related Skills

accessibility-commerce

11
from finsilabs/awesome-ecommerce-skills

Make your store usable by everyone with WCAG 2.1 AA compliance — screen reader support, keyboard navigation, and accessible cart and checkout flows

gdpr-ecommerce

11
from finsilabs/awesome-ecommerce-skills

Make your store GDPR-compliant with cookie consent, customer data export on request, right-to-deletion workflows, and data processing agreements

ab-testing-pricing

11
from finsilabs/awesome-ecommerce-skills

Test different price points with proper statistical rigor to find the revenue-maximizing price while tracking conversion rate and margin impact

woocommerce-subscriptions

11
from finsilabs/awesome-ecommerce-skills

Add subscription products to WooCommerce with automatic recurring billing, renewal notifications, and subscriber self-service management

woocommerce-rest-api

11
from finsilabs/awesome-ecommerce-skills

Integrate or build headless frontends on WooCommerce using its REST API for products, orders, customers, and coupons with key authentication

woocommerce-plugin-development

11
from finsilabs/awesome-ecommerce-skills

Create custom WooCommerce plugins using action/filter hooks, the Settings API, and REST API extensions to add features without modifying core

woocommerce-performance

11
from finsilabs/awesome-ecommerce-skills

Fix slow WooCommerce stores by optimizing database queries, clearing transients, enabling Redis object caching, and configuring page caching

woocommerce-blocks

11
from finsilabs/awesome-ecommerce-skills

Customize WooCommerce checkout and cart pages using Gutenberg blocks with server-side rendering, slot-fills, and extensibility hooks

video-commerce-integration

11
from finsilabs/awesome-ecommerce-skills

Enable shoppable video experiences with live shopping events, interactive product hotspots, and one-click checkout directly from video and livestream content

social-commerce

11
from finsilabs/awesome-ecommerce-skills

Sync your catalog to Instagram, TikTok, and Facebook to enable shoppable posts and in-app checkout directly from your social content

google-ads-ecommerce

11
from finsilabs/awesome-ecommerce-skills

Build and optimize Google Ads campaigns for ecommerce with Performance Max, Shopping feeds, conversion tracking, and Smart Bidding strategies for ROAS

ecommerce-seo

11
from finsilabs/awesome-ecommerce-skills

Maximize organic search traffic with optimized product page meta tags, JSON-LD structured data for Google Shopping, and automated XML sitemaps