Weather scenarios¶
Weather scenarios are 20 pre-calibrated presets that combine several Performance Chaos levers (backend + frontend) into a single student click. They are defined in the PerformanceScenario.java class as an immutable catalog (PerformanceScenario.ALL) and exposed to the student through GET /api/chaos/student/performance/scenarios.
Each scenario carries an opaque weather-themed name (Light breeze, Sandstorm…) — the student sees neither the enabled levers nor their intensity. This is intentional: the goal is for them to diagnose the behavior from the observability dashboards rather than by reading the chaos configuration.
Levels N1 → N4¶
Scenarios are organized into 4 levels of progressive difficulty, named N1 through N4 (not to be confused with the unified 0 – 4 levels of the other chaos families):
| Level | Label | Scenarios | Pedagogical profile |
|---|---|---|---|
| N1 | Junior | N1-01 → N1-05 | Basic diagnosis — a single dominant lever |
| N2 | Intermediate | N2-01 → N2-05 | Combinations of 2 consistent levers |
| N3 | Expert | N3-01 → N3-05 | Differential diagnosis, multiple levers |
| N4 | Master | N4-01 → N4-05 | Extreme saturation — every indicator in the red |
Freemium¶
Only N1-01 (Light breeze) and N1-02 (Morning mist) are accessible without a license. The 18 other scenarios return HTTP 402 (LICENSE_REQUIRED) to the freemium student. The instructor retains full access through the chaos-admin panel.
Full catalog¶
The values below are extracted directly from PerformanceScenario.buildCatalogue(). The columns represent the intensities applied to backend and frontend levers; a dash means the lever is inactive (value 0 or default).
Level N1 — Junior¶
| ID | Name (FR) | Free | CPU | Mem | DB | Thrd | SQL | Net | FE-Mem |
|---|---|---|---|---|---|---|---|---|---|
| N1-01 | Brise légère | ✅ | 40 | — | — | — | — | — | — |
| N1-02 | Brume matinale | ✅ | — | — | — | — | — | — | 30 |
| N1-03 | Grain passager | ❌ | — | — | — | — | 40 | — | — |
| N1-04 | Crachin réseau | ❌ | — | — | — | — | — | 30 | — |
| N1-05 | Nuage de passage | ❌ | 30 | 20 | — | — | — | — | — |
Level N2 — Intermediate¶
| ID | Name (FR) | CPU | Mem | DB | Thrd | SQL | Net | FE-Fch |
|---|---|---|---|---|---|---|---|---|
| N2-01 | Vent de travers | 60 | — | — | — | 50 | — | — |
| N2-02 | Étang gelé | — | — | 50 | — | — | — | — |
| N2-03 | Bourrasque | 40 | — | — | 60 | — | — | — |
| N2-04 | Brouillard double | 30 | — | — | — | — | — | 60 |
| N2-05 | Marée montante | — | 60 | — | — | — | — | — |
Note N2-05:
memoryHeapCapis lowered to 70 % (instead of the default 80 %) to tighten the guardrail.
Level N3 — Expert¶
| ID | Name (FR) | CPU | Ratio | Mem | DB | Thrd | SQL | DL | Net | FE-Mem |
|---|---|---|---|---|---|---|---|---|---|---|
| N3-01 | Tempête de sable | 80 | 3 | — | — | — | 60 | — | — | — |
| N3-02 | Gel profond | — | — | — | 70 | — | — | 40 | — | — |
| N3-03 | Déluge croisé | — | — | 80 | — | — | — | — | — | 70 |
| N3-04 | Front orageux | — | — | — | — | 70 | — | — | 70 | — |
| N3-05 | Cyclone en formation | 70 | 2 | — | 60 | — | 40 | — | — | — |
Note N3-03:
memoryHeapCaplowered to 50 % — the backend memory leak is capped earlier and combined with a frontend memory leak.
Level N4 — Master¶
| ID | Name (FR) | CPU | Ratio | Mem | DB | Thrd | SQL | DL | Net | FE-all |
|---|---|---|---|---|---|---|---|---|---|---|
| N4-01 | Ouragan | 95 | 5 | — | — | — | — | — | — | — |
| N4-02 | Effondrement | — | — | — | 90 | 80 | — | 70 | — | — |
| N4-03 | Point de rupture | — | — | 105 | — | — | — | — | — | — |
| N4-04 | Tsunami | 50 | — | — | — | — | — | — | — | 100 |
| N4-05 | Tempête parfaite | 80 | — | 70 | 80 | — | 70 | — | 60 | — |
N4 notes:
- N4-03 Point de rupture:
memory = 105+memoryHeapCap = 100→ this is the intentional OOM mode. The scenario deliberately triggers anOutOfMemoryError— useful for generating a pedagogical heap dump to analyze with Eclipse MAT.- N4-04 Tsunami: simultaneously enables all four frontend chaos levers at 100 % (
feCpuBurn,feMemoryLeak,feDomFlood,feFetchFlood) in addition to a backend CPU at 50 %.- N4-05 Tempête parfaite: combines 5 simultaneous backend levers.
Activation by the student¶
The student enables a scenario through POST /api/chaos/student/performance/scenario by sending a JSON body containing the scenario identifier:
curl -X POST https://perfshop-api.perfshop.io/api/chaos/student/performance/scenario \
-H "Content-Type: application/json" \
-d '{"scenarioId": "N2-03"}'
Success response:
The endpoint requires that student mode is enabled by the instructor (studentModeService.isEnabled()). Otherwise it returns 403 with student.error.blocked.
Error codes¶
| Code | Cause |
|---|---|
400 |
Unknown scenarioId (student.scenario.unknown) |
402 |
LICENSE_REQUIRED — scenario out of freemium |
403 |
Student mode disabled by the instructor |
Deactivation¶
To deactivate the active scenario, the student sends an empty string:
curl -X POST https://perfshop-api.perfshop.io/api/chaos/student/performance/scenario \
-H "Content-Type: application/json" \
-d '{"scenarioId": ""}'
The backend then calls chaosService.resetAll() and frontendChaosController.resetState() — all Performance levers (backend and frontend) are reset to zero, not only those of the current scenario. The response is { success: true, scenarioId: "", active: false }.
Listing and current status¶
Returns the full list of 20 scenarios with, for each:
id— identifier N1-01 → N4-05level— N1 / N2 / N3 / N4name— weather name localized perPERFSHOP_LANGrequiresLicense— booleanaccessible— computed boolean (!requiresLicense || licenseValid)
The activeScenario field in the response body holds the identifier of the currently active scenario (empty string if none is active).
Pedagogical relevance¶
A few flagship scenarios and the diagnostic skill they target:
| Scenario | Targeted skill |
|---|---|
| N1-01 Brise légère | Read container_cpu_usage and correlate with p99 latency |
| N1-02 Brume matinale | Analyze a JS heap that grows in Chrome DevTools |
| N2-02 Étang gelé | Detect a hikaricp_connections_pending saturation |
| N2-04 Brouillard double | Distinguish backend network pressure from frontend flooding |
| N3-02 Gel profond | Differential diagnosis: DB pool + MySQL deadlock |
| N3-03 Déluge croisé | Distinguish backend memory leak from browser memory leak |
| N3-05 Cyclone formation | Three simultaneous levers — multi-metric correlation |
| N4-03 Point de rupture | Generation and analysis of a heap dump with Eclipse MAT |
| N4-04 Tsunami | Diagnosing a browser crash — four frontend vectors |
| N4-05 Tempête parfaite | Full synthesis — all previous skills |
Automatic reconciliation¶
The ChaosStudentController automatically reconciles the activeScenarioId field to null when all levers are at zero (isAllChaosOff() method). This prevents a scenario from still being displayed as "active" after a manual reset through the instructor panel.
Startup validation¶
Each scenario is validated by Builder.build() when the class is loaded: cpu ∈ [0, 100], cpuRatio ∈ [1, 5], memory ∈ [0, 100] ∪ {105}, memoryHeapCap ∈ [0, 100], etc. An out-of-range value raises an IllegalArgumentException at backend startup — the catalog is fail-fast.