118 lines
3.6 KiB
Markdown
118 lines
3.6 KiB
Markdown
# HOALedgerIQ – Load Test Improvement Report
|
||
**Cycle:** 001
|
||
**Date:** YYYY-MM-DD
|
||
**Test window:** HH:MM – HH:MM UTC
|
||
**Environments:** Staging (`staging.hoaledgeriq.com`)
|
||
**Scenarios run:** `auth-dashboard-flow.js` + `crud-flow.js`
|
||
**Peak VUs:** 200 (dashboard) / 100 (CRUD)
|
||
**New Relic app:** `HOALedgerIQ_App`
|
||
|
||
---
|
||
|
||
## Executive Summary
|
||
|
||
> _[One paragraph: what load the system handled, what broke first, at what VU threshold, and the estimated user-facing impact. Written by Claude Code from New Relic data.]_
|
||
|
||
**Threshold breaches this cycle:**
|
||
|
||
| Metric | Target | Actual | Status |
|
||
|--------|--------|--------|--------|
|
||
| login p95 | < 300ms | — | 🔴 / 🟢 |
|
||
| dashboard p95 | < 1000ms | — | 🔴 / 🟢 |
|
||
| budget vs-actual p95 | < 1000ms | — | 🔴 / 🟢 |
|
||
| journal entry write p95 | < 1200ms | — | 🔴 / 🟢 |
|
||
| error rate | < 1% | — | 🔴 / 🟢 |
|
||
|
||
---
|
||
|
||
## Findings
|
||
|
||
### 🔴 P0 – Fix Before Next Deploy
|
||
|
||
#### Finding 001 – [Short title]
|
||
- **Symptom:** _e.g., `GET /api/reports/cash-flow-forecast` p95 = 3,400ms at 100 VUs_
|
||
- **New Relic evidence:** _e.g., DatastoreSegment shows 47 sequential DB calls per request_
|
||
- **Root cause hypothesis:** _e.g., N+1 on `reserve_components` — each component triggers a separate `SELECT` for `monthly_actuals`_
|
||
- **File:** `backend/src/modules/reports/cash-flow.service.ts:83`
|
||
- **Recommended fix:**
|
||
```typescript
|
||
// BEFORE – N+1: one query per component
|
||
for (const component of components) {
|
||
const actuals = await this.actualsRepo.findBy({ componentId: component.id });
|
||
}
|
||
|
||
// AFTER – batch load with WHERE IN
|
||
const actuals = await this.actualsRepo.findBy({
|
||
componentId: In(components.map(c => c.id))
|
||
});
|
||
```
|
||
- **Expected improvement:** ~70% latency reduction on this endpoint
|
||
- **Effort:** Low (1–2 hours)
|
||
|
||
---
|
||
|
||
### 🟠 P1 – Fix Within This Sprint
|
||
|
||
#### Finding 002 – [Short title]
|
||
- **Symptom:**
|
||
- **New Relic evidence:**
|
||
- **Root cause hypothesis:**
|
||
- **File:**
|
||
- **Recommended fix:**
|
||
- **Expected improvement:**
|
||
- **Effort:**
|
||
|
||
#### Finding 003 – [Short title]
|
||
- _(same structure)_
|
||
|
||
---
|
||
|
||
### 🟡 P2 – Backlog
|
||
|
||
#### Finding 004 – [Short title]
|
||
- **Symptom:**
|
||
- **Root cause hypothesis:**
|
||
- **Recommended fix:**
|
||
- **Effort:**
|
||
|
||
---
|
||
|
||
## Regression Net — Re-Test Criteria
|
||
|
||
After implementing P0 + P1 fixes, the next BlazeMeter run must pass these gates before merging to staging:
|
||
|
||
| Endpoint | Previous p95 | Target p95 | k6 Threshold |
|
||
|----------|-------------|------------|-------------|
|
||
| `GET /api/reports/cash-flow-forecast` | — | — | `p(95)<XXX` |
|
||
| `POST /api/journal-entries` | — | — | `p(95)<XXX` |
|
||
| `GET /api/budgets/:year/vs-actual` | — | — | `p(95)<XXX` |
|
||
|
||
> **Claude Code update command (run after confirming fixes):**
|
||
> ```bash
|
||
> claude "Update load-tests/analysis/baseline.json with the p95 values from
|
||
> load-tests/reports/cycle-001.md findings. Tighten the k6 thresholds in
|
||
> load-tests/config/environments.json staging block to match. Do not loosen
|
||
> any threshold that already passes."
|
||
> ```
|
||
|
||
---
|
||
|
||
## Baseline Delta
|
||
|
||
| Endpoint | Cycle 000 p95 | Cycle 001 p95 | Δ |
|
||
|----------|--------------|--------------|---|
|
||
| _(populated after first run)_ | — | — | — |
|
||
|
||
---
|
||
|
||
## Notes & Observations
|
||
|
||
- _Any anomalies, flaky tests, or infrastructure events during the run_
|
||
- _Redis / BullMQ queue depth observations_
|
||
- _Rate limiter (Throttler) trip count — if >0, note which endpoints and at what VU count_
|
||
- _TenantMiddleware cache hit rate (if observable via New Relic custom attributes)_
|
||
|
||
---
|
||
|
||
_Generated by Claude Code. Source data in `load-tests/analysis/raw/`. Next cycle target: implement P0+P1, re-run at same peak VUs, update baselines._
|