Scale, Health Checks and Final Tuning
This example is the capstone. The application is the finished one: every scenario inside its budget, the leak gone, and now a Capacity screen that turns the measurements into thresholds and shows the instance answering a load balancer.
Capacity.md— the model and its arithmeticDeployment.md— two instances, session affinity, the WebSocket pathMonitoring.md— counters, alerts, and what each fix regressing looks likeFinalReport.md— all six modules in one document
Run it
cd "LearnWisej-Samples/Performance and Profiling Course/Module 7/WisejPerfLab"
dotnet run -c Release -f net10.0 --urls http://localhost:5807
The health URL a load balancer would poll is http://localhost:5807/healthcheck.wx.
What to click
| Action | What you should see |
|---|---|
| Capacity tab | sessions 1 memory 0 % CPU 0 % managed heap 40.7 MB, the HealthCheck.json values, and the capacity model with every number sourced to the module that measured it |
| Ask healthcheck.wx now | healthcheck.wx → 200 OK and available — 1 session(s), memory 0 %, CPU 0 % |
| Drive it past the session limit | the answer turns red: 503 (Retry-After: 10) — sessions 1 >= maxSessions 1 |
| now click anything else | the running session is untouched — every tab still works. That is the whole point of a health check |
| open a second browser tab while over the limit | a real load balancer sends it elsewhere; with only this instance, /healthcheck.wx is the thing to watch — curl -i http://localhost:5807/healthcheck.wx returns 503 and Retry-After: 10 |
| Restore the configured limit | 200 OK again |
| Run the three scenarios ×3 | every median inside its budget: refresh ~113 ms, search ~66 ms, tree expand ~9 ms |
| Warm up, Memory snapshot A → ×50 → Snapshot B | heap +1.1 MB subscribers 0 |
curl -i http://localhost:5807/healthcheck.wx
What changed since Module 6
HealthCheck.json new — enabled, maxMemory, maxSessions, maxCPU, returnCode, retryAfter
Health/CapacityModel.cs new — the measured inputs and the arithmetic, in code
Health/HealthPolicy.cs new — HealthCheck.IsServerAvailable, the reason for the last answer,
and the lab override that refuses new sessions
Health/ServerLoad.cs new — memory % and CPU % (Wisej's own accessors are not public)
Pages/CapacityPage.cs new — the Capacity tab
MainPage.cs / .Designer.cs + the fourth tab
Shell/PerfBudget.cs + Capacity/HealthCheck, budget 20 ms — a health check must be free
Startup.cs + HealthPolicy.Apply() and the /healthcheck.wx endpoint
Known simplifications
- Wisej.NET's built-in
healthcheck.wxhandler belongs to the classic System.Web pipeline; under Kestrel it answered200whatever the limits were (verified on Wisej-4 4.1.0), so this sample serves the URL from its own middleware using the same configuration and the same availability function. See the last section ofDeployment.md. ServerLoadcomputes memory and CPU percentages itself, becauseHealthCheck.GetMemoryUsed()andGetCPULoad()are not public. On this machine they read 0–3 %, somaxSessionsis the threshold that fires.- 150 sessions is derived, not observed. A load test that actually holds 150 sessions is the open
item at the top of the remaining risks in
FinalReport.md.