deniz.in

Markets

Weather

Loading weather

· via dev.to (home feed)

Memory64 lifts WebAssembly's 4GB heap ceiling but leaves a JavaScript ABI gap

A dev.to report shows Memory64 enabling a 473-million-parameter WebAssembly allocation the 32-bit heap could not make, while a Number-versus-BigInt pointer mismatch still forces larger in-browser presets onto the old path.

Memory64 lifts WebAssembly's 4GB heap ceiling but leaves a JavaScript ABI gap

The 4GB ceiling in practice

Classic WebAssembly modules address a linear memory with 32-bit pointers, which caps the heap at 4GB. For inference that is already tight, but for training it is worse: a model in fp32 needs four bytes per parameter for the weights alone, and optimizers such as AdamW keep additional per-parameter state, multiplying the footprint well beyond the raw weight tensors. According to the dev.to post, that arithmetic put the practical ceiling for an fp32 model with weights and AdamW state at roughly 250 million parameters — a serious constraint for anyone trying to build a browser-based training playground.

What Memory64 changed

Memory64 widens WebAssembly's pointer width to 64 bits, and on the JavaScript side it requires BigInt, because a JavaScript Number — a 64-bit floating-point value — cannot represent every 64-bit integer exactly. The developer behind the post recompiled the same C++ source with Memory64 and BigInt support enabled and reran the allocation benchmark.

The measured results were unambiguous. The 64-bit module allocated 473,244,160 parameters in 3.7 seconds, completed a single training step in 82.2 seconds, and released the allocation cleanly afterwards. The 32-bit build of the same code could not perform the allocation at all. In other words, the theoretical memory ceiling did move, and by a wide margin — the successful run sits well beyond what the old heap could physically address once optimizer state is included.

Where the run stopped short

The catch is that the benchmark ran under Node, which does not exercise the browser's JavaScript-to-WebAssembly bridge. When the developer took the work toward the actual in-browser workflow, pointer values crossed that boundary inconsistently: in one place they arrived as Number, in another as BigInt. Because the two sides of the bridge disagreed on the pointer type, the larger in-browser presets fell back to the 32-bit code path — back under the original 4GB constraint.

The post is explicit that the honest reading has two parts. Memory64 moved the allocation ceiling in a controlled, measured run, and the product path still contains an ABI integration blocker. A one-off successful allocation under Node did not prove that the full browser workflow works at the new scale. The measurements and the current limitation are recorded in the project's public devlog.

Why it matters

This story is a useful snapshot of where in-browser machine learning actually stands. The engine-level capability has arrived: wasm64 heaps can hold multi-hundred-million-parameter models with optimizer state, which was simply impossible under the 32-bit heap. But capability at the engine level is not the same as a working product path, and the remaining blocker here is unglamorous — an ABI mismatch between Number and BigInt at the JavaScript boundary, exactly the kind of integration detail that benchmark runs in Node never touch.

For developers porting large native ML codebases to WebAssembly, the lesson is to plan for the boundary early. Any code that passes pointers between JavaScript and a Memory64 module has to commit to BigInt consistently, or it will silently degrade to the old 32-bit path and the old 4GB ceiling. If that integration gap closes, browsers become a plausible environment for training and fine-tuning models roughly twice the size of what was previously feasible — which changes what in-browser AI tools can realistically attempt.

  • #webassembly
  • #memory64
  • #javascript
  • #bigint
  • #in-browser-ai