Run the stress test and observe degradation
Running the stress test is where you shift from theory to observation. As k6 ramps through each stage, you watch for specific failure signals that tell you how your system handles overload. The signals you’re looking for are different from baseline testing: instead of confirming everything passes, you’re tracking where and how things start to fail.
If you’re testing against QuickPizza, the system is designed to be performant and may handle 2-3x load without visible degradation. That’s fine. Focus on learning to read the output and identify where you would see these signals. The example outputs below show what degradation looks like when a system reaches its limits. When you apply this technique to your own services, these are the patterns to watch for.
To run the stress test and identify failure signals, complete the following steps:
Open your terminal and run the stress test:
k6 run stress.jsWatch the real-time output as k6 ramps through each stage. Pay attention to how metrics change as VU count increases.
Note: From k6 v1.0.0 onward, the default end-of-test printout is compact summary mode (see End of test and
--summary-mode). The snippets below match that layout: headings such as TOTAL RESULTS and subsection labels such as HTTP, then dotted metric lines. If you pass--summary-mode=legacy, alignment follows the pre-v1.0.0 format instead.When the test completes, open the summary and inspect
http_req_failed.During the baseline phase (20 VUs), this value should be near zero. If it climbs during the 2x or 3x stages, note the point where errors first appear. In compact mode,
http_req_failedsits under the HTTP heading. For example:█ TOTAL RESULTS checks_total.......................: 2398 11.2/s checks_succeeded...................: 94.20% 2260 out of 2398 checks_failed......................: 5.80% 138 out of 2398 HTTP http_req_duration..................: avg=680ms min=95ms med=420ms max=8500ms p(90)=1200ms p(95)=2100ms http_req_failed....................: 3.42% 82 out of 2398 http_reqs..........................: 2398 11.2/sAn error rate that jumps from 0% to 3% or higher during elevated stages means the system can’t handle the additional load cleanly.
Compare
http_req_durationpercentiles against your baseline values.For example, if your baseline p95 was 350 ms and the stress test shows a p95 of 2.1 s, the system is significantly slower under load. In compact mode,
http_req_durationis a single line under HTTP (same excerpt as step 2). Amaxvalue that’s dramatically higher than the p95 indicates timeout-level delays for some requests.Review the checks section.
Checks that passed at baseline but fail under stress reveal correctness problems caused by overload. Compact mode shows
checks_total,checks_succeeded, andchecks_failedunder TOTAL RESULTS (see step 2 excerpt). Individual check names appear below those lines when checks pass or fail.Scan the k6 output for connection resets and timeouts.
Errors like
dial: i/o timeoutorread: connection reset by peermean the system or network is actively refusing connections under load. Those lines usually appear on stderr while the test is running and can scroll past, so watch during the run or save the terminal output if you need them later. The end-of-test summary still shows overall error rate and failed requests even when you don’t see every underlying message repeated there.Correlate the failure signals with the load stages.
If you see degradation: at what VU count did it begin? If errors first appeared during the 2x stage (40 VUs), that’s your degradation threshold. If everything was fine at 2x but broke at 3x (60 VUs), the system has more headroom than expected.
If you see no degradation: note that the system stayed healthy through all stress stages and record the VU count and throughput at your highest stage (for example, 60 VUs). That clean run is a valid outcome to capture in your results table.
Note: Some degradation is expected and healthy. A system that handles 3x normal load with only a modest latency increase is performing well. Watch for strong warning signs, for example error rates climbing into mid single digits or higher (your thresholds may differ), latency far above what you accept for your SLOs, or checks that were passing at baseline now failing consistently.
If you’re testing against QuickPizza and see no degradation at all, that’s a valid result: it means the system handles this load level comfortably. The methodology still applies: you’ve confirmed that 60 VUs is within QuickPizza’s capacity. To find real limits in your own systems, substitute your own endpoint and adjust the VU targets based on your expected production traffic.
You can now read degradation signals in the k6 compact summary and tie them to load stages, or confirm a clean run through all stress stages.
In the next milestone, you document your stress results in a table: either the VU count and RPS where strain first appeared, or healthy metrics across all stages if the run stayed clean.
Please tell us what didn't work: