RIVLET

Benchmarks

Measured inference latency.

Every speed number we publish comes from the harness below — real headless Chrome, the same forward pass the live demo runs, full methodology and caveats in the open. No estimates, no asterisks you can’t check.

Headline: 1.71 ms median · 1.81 ms p95 · 581/s per classification, in your browser.

In-browser results

Production canonical bundles only — the int8 artifacts the SDK actually loads.

ModelRolep50p95pred/sTop-1 / Top-3Bundle
rivlet-listen-v0Listen — 35-class keyword spotting (GSCv2)1.71 ms1.81 ms581>80% / >93%6.43 MB · 622 KB gz
voice-numbers-v0Digits 0–9 (int8) — /customize Number Entry1.69 ms1.8 ms58890.0% / 97.05%8.77 MB

How we measured

Runtime
Real Chrome (headless Playwright Chromium) — V8 within 0.03 ms of Node V8
Machine
MacBook Pro M4 Max · single-threaded (no SharedArrayBuffer thread pool — same path as the live demo)
Iterations
3,000 timed iterations + 500 warm-up
Input
Synthetic 1.0 s / 16 kHz mono / 440 Hz sine
Per-iteration
mel-spectrogram → AudioRoutedClassifier::classify_dual → action-head softmax — the exact call the in-browser demo runs

Caveats — what we’d flag if you cited these

  • CPU frequency is not pinned (M-series macOS has no cpupower); a thermally idle machine is assumed.
  • Input is synthetic and deterministic — compute shape is content-independent, so the run reproduces bit-for-bit.
  • Native Rust on the same machine runs ~1.1–1.4 ms (≈1.5× faster); the browser figures above are what a user actually experiences.
  • These are M4 Max desktop-class numbers. Phone numbers are not yet measured.

For context

A measured on-device reference point — whisper.cpp tiny on the same M4 Max class machine — so the ~1.7 ms classification number has a frame. It is deliberately apples-to-oranges: transcription is a heavier, open-vocabulary job than closed-set classification.

~74 ms / 1 s audio

Whisper.cpp tiny (on-device STT)

Measured by us on Apple M4 Max: whisper.cpp tiny.en (1.8.6) transcribing a ~1 s clip — p50 74 ms, p95 81 ms (greedy decode, 8 threads, model resident; +40 ms one-time model load). A heavier transformer doing a different, harder job — open-vocabulary transcription, not closed-set classification — on the same CPU class.

Run it yourself

Benchmark on your own device.

The exact forward pass the table above measures, run right here in your browser. Pick a model and hit run — 300 warm-up + 2,000 timed classifications on a synthetic 1 s / 16 kHz / 440 Hz sine — then your numbers land next to ours.