Where does the shop break when visitors come to buy, not to look?

Online shop on Black Friday

Limit found — provisional

Holds ~30 req/s on short steps (2.1 min), fails at ~35 req/s

Failed checks: Choose shipping errors 1.2 % > 1 %, Open categories errors 1.4 % > 1 %, Search errors 1.8 % > 1 %.

Holds
~30req/s
measured over 2.1 min
Fails at
~35req/s
judged by the SLO

Checked 6 of 12 steps at this rate; 6 not checked — too few samples (< 100 in the window)

  • Choose shipping
  • Place the order
  • Start payment
  • Open the payment session
  • See shipping options
  • Enter the address

rate steps of 2.1–7 min · checks: 149 passed, 5 failed, 6 too little data, 0 not run · sent 99 % of the plan · generator health not verified

Synthetic load sent from outside; your real traffic and server metrics are not part of it.

What to do next

  1. Confirm it with a load test at ~24 req/s.
  2. To check Choose shipping, Place the order, Start payment and 3 more, run at least 4.7 min at this rate: they had fewer than 100 samples.

The large catalog under a sale-day visit mix at a steady rate: fewer browsers, more carts and orders per visit. It models the mix, not a sale-day traffic spike.

Example: a real CapacityLab Load Run against a shop we host

Test setup

Where the limit lies

Each dot is a rate the shop was held at for at least a minute and a half. It passes when every step of the visit with enough samples keeps its p95 latency inside the bound and errors under 1%; a rare checkout step with too few samples at that rate is shown as missing, not as passed.

Holds30.3 req/sBreaks by35.3 req/sThe limit lies in between
  • Held for 30 min24.5 req/s
  • Held for 60 min24.5 req/s
  • Held for 180 min24.5 req/s
  • Held for 720 min24.5 req/s
Slowed first
Search
Latency bound
p95 ≤ 1.5 s

Planned against delivered

The search climbs a staircase of rates. At each step our generators sent the planned rate; the bars show what the shop actually answered, and its p95 latency at that step.

020406001 s2 sp95 ≤ 1.5 s for every step30.335.341.248Planned, req/s
PlannedDeliveredp95 (right scale)
PlannedDeliveredp95ErrorsResult
30.329.9750 ms0.5%Held
35.335750 ms0.65%Broke
41.240750 ms0.75%Broke
4847.2750 ms0.93%Broke
Why 35.3 req/s broke
  • Choose shipping: 1.18% of requests failed, against 1% allowed.
  • Open categories: 1.39% of requests failed, against 1% allowed.
  • Search: 1.84% of requests failed, against 1% allowed.
Why 41.2 req/s broke
  • Search: 2.87% of requests failed, against 1% allowed.

Which step slowed down first

p95 latency of each step of the visit at each rate, against the bound. The step the Result names as limiting is marked.

Which step slowed down first
Step of the visitShare30.3 req/s35.3 req/s41.2 req/s
Load the regionGET /store/regions
3.9%
75 ms0.7% errors
100 ms
100 ms0.6% errors
Open categoriesGET /store/product-categories
8.6%
100 ms0.6% errors
75 ms1.4% errors
100 ms0.5% errors
Browse the catalogGET /store/products
24%
100 ms0.7% errors
100 ms0.3% errors
100 ms0.4% errors
SearchLimitingGET /store/products
12%
750 ms0.9% errors
750 ms1.8% errors
750 ms2.9% errors
Open a productGET /store/products/{product_id}
37%
100 ms0.3% errors
100 ms0.5% errors
100 ms0.6% errors
Add to cartPOST /store/carts
3.9%
500 ms0.7% errors
500 ms
500 ms
Enter the addressPOST /store/carts/{cart_id}
2.2%
—
1,000 ms0.6% errors
750 ms0.7% errors
See shipping optionsGET /store/shipping-options
2.2%
—
300 ms
300 ms
Choose shippingPOST /store/carts/{cart_id}/shipping-methods
2.2%
—
1,500 ms1.2% errors
1,000 ms0.4% errors
Start paymentPOST /store/payment-collections
1.2%
—
300 ms
300 ms0.7% errors
Open the payment sessionPOST /store/payment-collections/{payment_collection_id}/payment-sessions
1.2%
—
200 ms
200 ms
Place the orderPOST /store/carts/{cart_id}/complete
1.2%
—
1,000 ms
1,000 ms

p95, SLO ≤ 1,500 ms

Holding it for longer

A capacity search finds the limit in minutes. Longer runs at a rate below it show whether the shop keeps holding: slow leaks, full queues and cold caches take time to show.

  1. Find the limitLimit found — provisionalHolds ~30 req/s on short steps (2.1 min), fails at ~35 req/sOct 2, 2026, 16:05 UTC
  2. Hold 30 minHeld24.6 req/s delivered, p95 500 ms, errors 0%Sep 30, 2026, 18:45 UTC
  3. Hold 1 hHeld24.4 req/s delivered, p95 500 ms, errors 0.01%Sep 30, 2026, 19:17 UTC
  4. Hold 3 hHeld24.5 req/s delivered, p95 500 ms, errors 0%Sep 30, 2026, 20:19 UTC
  5. Hold 12 hHeld24.5 req/s delivered, p95 500 ms, errors 0.04%Sep 30, 2026, 23:34 UTC

What we saw on our own servers

This is the one part a Report does not contain: we host this shop, so we can read its hosting metrics. On your application you read your own dashboards; CapacityLab measures from the outside.

  • Application (Node.js)1.28 vCPUMemory peak 678 MB
  • Database (PostgreSQL)11 vCPUMemory peak 5,328 MB
  • Cache (Redis)0.02 vCPUMemory peak 28 MB

The database was the busier side: its CPU peaked at 11 vCPU while the application stayed at 1.28. Its CPU was not capped, so this shows where the work went, not that the database ran out; search over a catalog this large is database work and a likely place for visitors to queue, but locks and query plans were not measured.

188 of 47,592 requests ended with a server error.

What you would do next

  1. Confirm before you plan

    Run a load test at 24.2 req/s for 30 minutes: the search advises it as the rate to confirm next, and only the confirmation shows whether every step keeps its bound.

  2. Watch your side while it runs

    Keep your own dashboards open during the run. The report says which step slowed; your metrics say why.

  3. Change one thing, then compare

    After a change, run the same test again and put the two reports side by side.

Your own copy of this report is one sign-up away

Sign up with your email. Your new account opens with this report and every other demo report inside, ready to compare with your own first run.

Open this report in your account Free sign-up. The report is waiting in your new account, with $5 of credit for your own first run.

Where these numbers come from

Exported from the published Reports of these Load Runs. The shop's CPU and memory come from its Railway metrics; its error count from its own access log.

Identifiers and checksums
Load RunResult digestComputed
2f2bc0b7-b0c8-49a3-82d4-1c138209e73bsha256:386667c70d9ca0840cdee6aeb1acd1a6c07e3922ec9adb555910568ba8dfd39eOct 2, 2026, 16:25 UTC
4d174fec-5654-4ade-a097-f56b69567486sha256:b67c3b95dc3c4ae89398b1c4910ae7c7fb08ee5904f5e7ba37df34630432e2c4Sep 30, 2026, 19:16 UTC
0eacc785-d9b2-4233-971f-e7e55af25f05sha256:860d8d217e03cc4923877b350f95fbd864151bbb07a460e7b05b0d040db2385bSep 30, 2026, 20:18 UTC
843bd07c-9dc7-4e21-b0e2-5e3e983ade22sha256:3bc313613e1fa767f8632d5143cacee30d4958ffde2585f3dc41db8f5700425bSep 30, 2026, 23:20 UTC
172d3b8d-a7de-423e-987a-ffd27b0dd14bsha256:f85696037294e3e70e8e607c4ee8298c4b8b648ae8881a53da7bf4501642e83fOct 1, 2026, 11:37 UTC