Skip to content

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: memoryHeapCap is 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: memoryHeapCap lowered 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 an OutOfMemoryError — 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:

{
  "success":    true,
  "scenarioId": "N2-03",
  "name":       "Bourrasque",
  "level":      "N2",
  "active":     true
}

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

curl https://perfshop-api.perfshop.io/api/chaos/student/performance/scenarios

Returns the full list of 20 scenarios with, for each:

  • id — identifier N1-01 → N4-05
  • level — N1 / N2 / N3 / N4
  • name — weather name localized per PERFSHOP_LANG
  • requiresLicense — boolean
  • accessible — 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.