Session Record — 2026-02-10 14:30
Session Record — 2026-02-10 14:30
Topic: k6 Load Testing Baseline on Raspberry Pi
What We Did
-
Set up k6 load testing on Raspberry Pi — Created a
~/k6-tests/directory with 3 test scripts and a runner. -
Wrote 3 k6 test scripts targeting
give-qa-cf.berkeley.edu: -
discovery.js— 7-endpoint browse flow simulating a donor exploring the site:- Homepage
/ - Featured funds
/api/funds/featured/ - Search
/api/searchresults?search=<term>(random from 5 terms) - Fund page
/fund/<id>(random from 5 fund IDs) - Area details
/areadetails?slug=<slug> - Billing countries
/billing/countries - Suggested funds
/api/funds/suggested/ - Default: 10 VUs, 2 min. Thresholds: p(95) < 3s, error rate < 10%.
- Homepage
-
checkout.js— Full checkout flow (up to gift create POST):- Homepage (session + CSRF)
- Fund page with cart params
- Gift details page
- Billing page
- Billing countries + subregion
- POST
/api/cybersource/gift/createwith CSRF token - Default: 5 VUs, 2 min. Note: can't test CyberSource iframe without a real browser.
-
stress.js— Combined 80/20 discovery/checkout mix with ramp stages:- 0→50 VUs (2 min), hold 50 (5 min), 50→100 (2 min), 100→0 (1 min)
- Thresholds: p(95) < 2s, error rate < 5%
-
Wrote
run-tests.sh— Runner script with modes:smoke,discovery,checkout,stress,all. Saves timestamped results to~/k6-tests/results/. -
Ran baseline tests — 3 test runs saved:
#### Smoke Test 1 (smoke_20260210_143428.txt) — 1 VU, 10s
- FAILED thresholds: error rate 100%, p(95) = 4.32s
- Fund page check failed (0/1) — likely hit a nonexistent fund ID
- Search was extremely slow: avg 5.98s
- Homepage: avg 195.92ms
- Featured: avg 454.27ms
- Overall http_req_duration: avg 1.07s, p(95) 4.32s
#### Smoke Test 2 (smoke_20260210_143542.txt) — 1 VU, 10s
- PASSED all thresholds
- All 7 checks passed (100%)
- Search: avg 1.24s (much better than test 1)
- Homepage: avg 253.77ms
- Featured: avg 436.85ms
- Fund page: avg 363.98ms
- Overall http_req_duration: avg 432.01ms, p(95) 1.0s
#### Stress Test (stress_20260210_143657.txt) — 0→100 VUs, 10 min
- Output truncated at 9m32s (95% complete, 586 iterations + 3 interrupted)
- At peak load (100 VUs), search endpoint started timing out:
Request Failed: Get "https://give-qa-cf.berkeley.edu/api/searchresults?search=research": request timeout
Request Failed: Get "https://give-qa-cf.berkeley.edu/api/searchresults?search=scholarship": request timeout
- No summary metrics available (output cut off before THRESHOLDS section)
- Search is clearly the bottleneck under load
Key Findings
| Metric | Smoke (1 VU) | Stress (100 VU peak) |
|---|---|---|
| Homepage | 195–254ms | N/A (no summary) |
| Search | 1.24–5.98s | Timeouts at peak |
| Fund Page | 272–364ms | N/A |
| Featured | 437–454ms | N/A |
| Overall p(95) | 1.0–4.32s | N/A |
- Search is the bottleneck: Even at 1 VU, search can take 6s. Under stress, it times out entirely.
- Homepage and fund pages are fast: Sub-400ms even without Cloudflare caching active.
- Stress test output was truncated — the terminal or tee command cut off before the k6 summary section. Need to investigate whether the test completed or was OOM-killed on the Pi.
Files on Raspberry Pi
~/k6-tests/
├── discovery.js # Browse/search flow (10 VUs, 2 min)
├── checkout.js # Checkout flow with gift create (5 VUs, 2 min)
├── stress.js # 80/20 mix, ramp 0→50→100→0 (10 min)
├── run-tests.sh # Runner: smoke|discovery|checkout|stress|all
└── results/
├── smoke_20260210_143428.txt # Smoke 1: FAILED (search slow, fund 404)
├── smoke_20260210_143542.txt # Smoke 2: PASSED (all endpoints OK)
└── stress_20260210_143657.txt # Stress: truncated at 95%, search timeouts
Next Steps
- [ ] Re-run stress test and ensure full output is captured (pipe to file, check for OOM)
- [ ] Re-run discovery test with Cloudflare caching active (post-cache-rule deployment) to compare against baseline
- [ ] Investigate search endpoint performance — likely needs DB query optimization or caching
- [ ] Add k6 checkout test with more realistic session handling