WASI preview 3: hilos y async en WebAssembly
Actualizado: 2026-05-03
Durante los últimos años, WebAssembly fuera del navegador ha crecido despacio pero con dirección. El gran cuello de botella ha sido siempre el mismo: el modelo de concurrencia. Preview 1 no tenía nada que se pareciera a hilos o async; preview 2 abrió la puerta al modelo de componentes pero dejó la concurrencia como asunto pendiente. Preview 3, que lleva meses en la fase final de estandarización, es por fin la pieza que faltaba.
Este post no pretende ser un tutorial exhaustivo de la API, sino un mapa mental: qué problema resuelve preview 3, cómo lo aborda y qué implicaciones tiene para los lenguajes y plataformas que lo adopten.
Puntos clave
- WASI preview 3 introduce concurrencia estructurada con primitivas componibles (futures, streams, tasks) en lugar de primitivas de bajo nivel de SO.
- Las primitivas son del modelo de componentes, no del runtime: la concurrencia puede cruzar fronteras entre lenguajes limpiamente.
- El impacto más importante es la portabilidad real entre plataformas serverless Wasm (Fastly Compute, Fermyon Spin, Cloudflare Workers).
- El comportamiento exacto de scheduling sigue siendo responsabilidad del runtime; el rendimiento puede variar entre Wasmtime y Wasmer.
- La adopción en lenguajes avanza desigual: Rust va bien, Go y Python tardarán más.
El problema que arrastrábamos
Antes de preview 3, ejecutar código WebAssembly concurrente fuera del navegador exigía trucos externos. Los runtimes (Wasmtime, WasmEdge) inventaban sus propias extensiones para ofrecer multi-threading, y cada lenguaje compilado a Wasm tenía que acomodarse como podía. Rust compilaba a wasm32-unknown-unknown sin soporte de hilos; si querías hilos, necesitabas runtimes específicos y técnicas de shared memory manualmente orquestadas.
El resultado era una plataforma que vendía portabilidad pero no la entregaba cuando tu aplicación necesitaba hacer dos cosas a la vez. Para cualquier carga seria (un servidor HTTP, un procesador de streams, un pipeline con concurrencia natural) tenías que elegir entre limitarte a lo sincrónico o saltar fuera del estándar.
El modelo que propone preview 3
Preview 3 introduce lo que el estándar llama concurrencia estructurada, y es más interesante que «hilos y async». En vez de ofrecer las primitivas de bajo nivel de un sistema operativo (mutex, condiciones, locks), preview 3 eleva el modelo a primitivas componibles:
- Futures: una operación que todavía no ha terminado pero promete producir un valor.
- Streams: una secuencia de valores que llegan en el tiempo, no todos juntos.
- Tasks: la unidad de ejecución concurrente que gestiona el scheduler.
Con esas tres primitivas se puede construir prácticamente cualquier patrón de concurrencia conocido, desde una llamada HTTP asíncrona hasta un pipeline de procesamiento en streaming.
Lo relevante es que estas primitivas son del modelo de componentes, no del runtime. Eso significa que un lenguaje que compile a Wasm puede ofrecer su propia sintaxis de async/await y traducirla a futures del modelo de componentes en el binario final. Cuando ese binario interactúa con otro componente —potencialmente escrito en otro lenguaje— la concurrencia atraviesa la frontera limpiamente.
Por qué es importante
El valor real de preview 3 no es que Wasm pueda hacer async, sino que puede hacerlo de forma estándar a través de los límites entre lenguajes. Esto tiene consecuencias prácticas:
- Un servidor HTTP escrito en Rust puede llamar, dentro del mismo binario, a un módulo Wasm escrito en Go que procesa streams. La llamada puede ser asíncrona y el flujo de datos puede ser streaming. Antes, o estabas atrapado en la misma implementación (todo Rust) o hacías la frontera sincrónica (lo que mata el rendimiento para cargas intensivas).
- Plataformas que ejecutan WebAssembly en producción (Fastly Compute, Fermyon Spin) pueden ahora soportar patrones asincrónicos de forma nativa, sin trucos específicos de cada plataforma. Es un paso grande hacia la portabilidad real de aplicaciones serverless Wasm entre proveedores.
- Los SDKs específicos de cada lenguaje van a converger. Hoy, escribir una función Lambda en Rust implica un SDK que expone primitivas async propias; en Go, otras distintas. Con preview 3 el estándar empuja a que todas las SDK hablen el mismo modelo, reduciendo fragmentación.
Relacionado, si te interesa la dirección general de WebAssembly más allá de la concurrencia, nuestro análisis de WASI preview 2 y el modelo de componentes explica la base sobre la que preview 3 construye. Y si estás evaluando WebAssembly como alternativa a contenedores para funciones serverless, el contexto de Cloudflare Workers y Fastly Compute Edge ayuda a situar cuándo encaja.
Lo que todavía no está resuelto
Pese al avance, preview 3 deja algunas cosas pendientes:
- Variabilidad entre runtimes: el mapeo de primitivas al modelo de threading nativo de cada runtime sigue siendo responsabilidad del runtime. El comportamiento exacto —cuántos hilos reales se crean, cómo se programan las tareas— puede variar entre Wasmtime, Wasmer y otros. En la práctica, ejecutar el mismo componente con concurrencia intensa en dos runtimes distintos puede dar rendimientos muy dispares, incluso si la corrección está garantizada.
- Interoperabilidad con código host: las funciones expuestas desde el runtime hacia el componente Wasm necesitan más trabajo. Hay casos límite, como cancelación durante una operación asíncrona, que aún están siendo pulidos.
- Adopción en lenguajes: Rust va bien encaminado con las ramas experimentales para preview 3. Go, Python y C++ están detrás, con estados variables.
Qué significa esto para el desarrollador
Si trabajas en una aplicación que ya usa WebAssembly fuera del navegador, preview 3 va a simplificar código que hoy depende de hacks específicos del runtime. Si estás empezando a explorar Wasm como alternativa a contenedores para funciones serverless, preview 3 es la versión en la que empezar a tomarlo en serio.
La aparición de preview 3 cierra el capítulo de «sí, pero…»: sí, Wasm funciona, sí, puedes usarlo en serio, sí, puedes hacer concurrencia decente. Mi intuición es que los próximos meses van a definir si WebAssembly se convierte en una plataforma de despliegue mainstream para servicios serverless, y preview 3 es probablemente la pieza que decide en qué dirección cae la balanza.