
CASE 01 · 2026 · Founder · Full-stack × ML
MIND PULSE PRO
Real-time behavioral stress detection that runs the model in the browser.
STATUS
SHIPPED PROTOTYPE — ENGINEERING EXPLORATION
RESULT
Browser-native stress scoring — 18.7ms P95 inference, fully offline, zero server round-trip.
LIMITATIONS
Signals captured from a single-user corpus; thresholds are not clinically validated.
⚠ This is an engineering prototype for behavioral-signal exploration — not a medical or diagnostic tool. Predictions require proper validation and informed consent.
01
THE PROBLEM
Stress is invisible until it isn't. Mental-health tools rely on self-reporting, which people game or skip. I wanted a system that reads stress from how you already work — keystrokes and mouse dynamics — without a single wearable.
Under 20ms inference — zero server round-trip
02
THE HARD PART
Getting inference under 20ms in the browser while keeping every prediction explainable — the model had to be small enough for the client, sharp enough to trust, and auditable end to end.
03
WHAT SHIPPED
Browser inference with zero server round-trip, plus a Tauri desktop client and fully offline WebLLM coaching — the whole ML stack runs on the user's machine.
THE FULL STORY
The story
Stress is a physiological signal that shows up in how you type before you'd ever admit
it in a survey. Self-reporting is the default tool, and it's gameable and skipped. The
insight: your keystroke timing, mouse velocity, and typing cadence are behavioural
signals nobody can fake easily.
The first version polled a REST endpoint every few seconds — 900ms of staleness on a
realtime problem. I rewrote the transport to WebSockets, pushed updates under 50ms, and
added mouse dynamics alongside the keyboard features. Then the bigger question: where
should the model run?
The browser won. Exporting XGBoost to ONNX and running it with onnxruntime-web
meant zero server round-trip, zero data leaving the machine, and offline coaching via
WebLLM. Under 20ms per prediction, with SHAP explaining every score. The model got
small enough to trust and auditable end to end — that combination is the real
contribution, more than any single benchmark.
IMPACT
- Under 20ms inference — zero server round-trip
- 50+ temporal features per typing session
- SHAP explainability for every prediction
- Fully offline coaching — no API keys exposed
THE ARCHITECTURE
Layered, labelled, honest — the system as it actually stands.
01 · SIGNAL CAPTURE
02 · FEATURE ENGINE
03 · INFERENCE
04 · EXPERIENCE
SYSTEM FLOW
WHAT IF …
Ask the project a different question. The architecture has to defend itself.
What if the model ran on the server, not the browser?
Latency would drop from 20ms to ~80ms on good networks (and much worse on Jio-tier mobile), privacy dies (keystroke patterns leave the device), and WebLLM's offline coaching becomes impossible. The browser was the constraint that forced the best architecture — 20ms inference with zero server cost and zero data leaving the machine. The trade is a ~1.5MB ONNX payload; I'd accept it again.
What if 10× users (10M typing sessions/day)?
The stateless design saves us: features are computed client-side, so load scales with the dashboard, not the model. I'd add: session-level feature stores with TTL, a clickhouse-style analytics sink for SHAP aggregates, and edge-cached onboarding — but the inference core stays client-side. Cost cliff: none for inference; infra spend stays ~flat.
DIVE DEEPER
Built it — now the descent. Each question opens the next layer: why, why this architecture, what broke, what I'd change.
01Why FastAPI + WebSockets?
Stress scoring is realtime by nature — polling added ~900ms staleness. WebSockets pushed updates under 50ms, and FastAPI kept the whole backend in one typed codebase.
02Why XGBoost instead of deep learning?
We extract 50+ tabular features from keystroke/mouse dynamics. XGBoost matched the accuracy of a small NN at a tenth of the latency, and ONNX made it run in the browser.
03What went wrong?
The first prototype polled a REST endpoint and overfit on keyboard-only features. I rewrote the transport to WebSockets and added mouse dynamics + SHAP so every prediction is auditable.
04What would I do now?
Distill to a smaller model, run federated feature extraction, and validate thresholds with a proper user study instead of my own typing.
THE REPO, INSIDE
Not a screenshot — a live iframe pulling this repo's README straight from the CDN.
THIS PROJECT LIVES IN A PRIVATE WORKSPACE