Skip to main content

#378 — browser/WASM cold-path budget + SLO proposal

We target the browser as a first-class runtime but have never written down a performance budget, so nothing tells us which featuresfeatureAn input signal a model conditions on. Beyond the raw tokens, Mailwoman feeds soft features — gazetteer-membership channels and the postcode anchor — that inform predictions without overriding them. are even shippable to a mid-range phone. This sets a proposed SLO and accounts for the cold path from measured artifact sizes + a node-side compute floor. What's measured vs estimated is marked — the in-browser P95 still wants a real device/headless trace (see Open).

Two budgets, not one

The browser geocoder has two distinct latency surfaces, and conflating them hides the real costs:

  1. Cold load — page open → first interactive parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.. One-time; network-dominated.
  2. Per-keystrokeparseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. + resolve on each input change. Steady-stateregionThe first-level administrative subdivision of a country — a US state, a French region, a province. The component between country and locality.; compute + query dominated.

Proposed SLO

SurfaceTarget (Moto-G-class phone, 4G)Bound by
Cold load (P95)< 6 s to first interactivethe 29 MB modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' fetch
Per-keystroke parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. (P95)< 50 msWASM inferenceinferenceRunning the trained model on new input to get predictions, as opposed to training, which produces the model. In Mailwoman that means a small transformer encoder reads an address string and classifies every token — house number, street, locality, region, postcode, and the rest. A Who's On First gazetteer can feed soft location hints into the pass, but the model makes the final call on every label. Where a generative model writes text token by token, Mailwoman's output is a retrieval-augmented token classification: one label per input piece.
Per-keystroke resolve (P95)< 50 msthe candidate-table SQLite probe

Cold-path accounting

What the loader (neural-web/loader.ts) fetches and runs before the first parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.:

ComponentSize / countSourceCost driver
int8 ONNXONNX (Open Neural Network Exchange). An open format for machine learning models that enables interoperability between training frameworks and inference runtimes. Mailwoman ships its trained model as an ONNX file so it can run in Node.js and the browser via onnxruntime. modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.'~29 MB (measured)HTTP fetch from R2the dominant cold cost — ~23 s @ 10 Mbps, ~4.6 s @ 50 Mbps
onnxruntimeONNX (Open Neural Network Exchange). An open format for machine learning models that enables interoperability between training frameworks and inference runtimes. Mailwoman ships its trained model as an ONNX file so it can run in Node.js and the browser via onnxruntime.-web WASMa few MB (estimated)HTTP + compileone-time WASM compile
tokenizertokenizerThe component that converts a raw address string into a sequence of numeric token IDs the model can process. Mailwoman's tokenizer is a SentencePiece unigram model trained specifically on postal addresses. + anchor + postcodepostcodeThe country-specific postal code (US ZIP, French code postal, etc.). Mailwoman handles postcode parsing entirely by rule classifier — a regex problem, not an ML one. bins~MB (estimated)HTTP fetchsmall
candidate.db warmupwarmupThe early phase of training where the learning rate ramps up from 0 to its peak value before cosine decay. Mailwoman uses a linear warmup.~12 cold byte-range fetches (measured, candidate-table spike)sql.js-httpvfs over a 1.3 GB R2 DBNOT a full download — header + B-tree nodes only
modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' session-init126 ms (measured, node native EP)localWASM EP is ~3–5× → est. ~400–600 ms in-browser
first (cold) parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.219 ms (measured, node; includes one-time lazy decoderdecoderIn a transformer encoder-decoder model, the part that produces output sequences. Mailwoman's classifier is encoder-only (no decoder); the 'CRF decoder' is a different thing — a structured-prediction layer that picks the best label sequence from the encoder's outputs./gazetteergazetteerA geographical index that maps place names and postcodes to real-world coordinates. Mailwoman uses a custom-built Who's On First (WOF) SQLite database as its gazetteer — the 'atlas' half of the grammar/atlas architecture. init)localamortized after the first parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates.

Per-keystroke floor (node native EP, measured): warm parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. 5.7 ms. The browser WASM EP runs ~3–5× slower, so a ~15–30 ms in-browser parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. is the realistic estimate — comfortably inside the 50 ms parseaddress parsingThe process of decomposing a free-text postal address string into structured components — house number, street name, locality, region, postcode, and country — so a geocoder can resolve them to coordinates. budget. The resolve half (the candidate-table SQLite probe) is the half we have NOT measured in-browser and is the suspected per-keystroke bottleneck (DeepSeek S45).

The bottleneck the numbers already name

Cold load is network-bound on the 29 MB modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.', not compute. The session-init (126 ms node → ~0.5 s WASM) and the ~12 candidate-table byte-range fetches are small beside a 29 MB sequential download. So the cold-load SLO is won or lost on modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' transfer size, which points the levers at: a smaller modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.' (distillation / structured pruning past int8), HTTP streaming + compile-while-download, and CDN edge-caching — not at the SQLite path.

Per-keystroke is the opposite — transfer is done, so it's WASM inferenceinferenceRunning the trained model on new input to get predictions, as opposed to training, which produces the model. In Mailwoman that means a small transformer encoder reads an address string and classifies every token — house number, street, locality, region, postcode, and the rest. A Who's On First gazetteer can feed soft location hints into the pass, but the model makes the final call on every label. Where a generative model writes text token by token, Mailwoman's output is a retrieval-augmented token classification: one label per input piece. (estimated in-budget) + the candidate SQLite probe (unmeasured, suspected bottleneck). This is exactly where the #372 flatbush pre-filter would help — pruning candidates by bbox before the name search. Per the diagnostic-before-fix discipline, #372 should be gated on the per-keystroke trace below, not built ahead of it.

Open — the empirical trace

These numbers bound the cold path from sizes + a compute floor, but the in-browser P95 on a real device (the SLO's actual gate) needs a browser trace: cold-load waterfall (modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.'/wasm/db fetch overlap), and a per-keystroke breakdown (WASM inferenceinferenceRunning the trained model on new input to get predictions, as opposed to training, which produces the model. In Mailwoman that means a small transformer encoder reads an address string and classifies every token — house number, street, locality, region, postcode, and the rest. A Who's On First gazetteer can feed soft location hints into the pass, but the model makes the final call on every label. Where a generative model writes text token by token, Mailwoman's output is a retrieval-augmented token classification: one label per input piece. vs the SQLite probe). That trace was blocked this shift — no Chrome on the lab box for the chrome-devtools profiler. Next step: run it against the live /demo from a machine with Chrome (or a throttled headless run), confirm the modelneural classifierThe machine learning model at the core of Mailwoman's parser — a transformer encoder (~30M parameters) trained from scratch to do BIO token classification over addresses. It learns the 'grammar' of address formats; the gazetteer supplies the 'atlas.'-fetch-dominates-cold hypothesis, and measure the resolve-half per-keystroke cost that gates #372.