WASI 0.3 et la mort des démarrages à froid : le Wasm côté serveur en production
Engineering Team
WASI 0.3 est là — et ça change tout
Le WebAssembly System Interface (WASI) 0.3 est sorti en février 2026, et il comble la dernière lacune qui empêchait le Wasm côté serveur d’entrer dans les charges de travail de production grand public. Avec l’async I/O natif, des types stream de première classe et le support complet des sockets TCP/UDP, les modules Wasm peuvent désormais faire tout ce qu’un conteneur peut faire — pour une fraction du coût de démarrage.
Si vous avez rejeté le Wasm sur serveur comme un jouet, cette version est votre signal pour reconsidérer. AWS, Google Cloud et Azure ont tous lancé des runtimes Wasm serverless en 2025-2026, et des entreprises comme Fermyon, Fastly et Cloudflare exécutent du Wasm en production à grande échelle depuis plus de deux ans.
Ce que WASI 0.3 apporte réellement
WASI 0.2 (janvier 2024) a introduit le Component Model et les interfaces I/O de base. WASI 0.3 s’appuie sur ces fondations avec trois ajouts critiques :
Async I/O natif
WASI 0.2 n’offrait que l’I/O bloquant. Si votre module Wasm devait gérer plusieurs connexions simultanées, vous étiez limité aux threads ou à des boucles de polling maladroites. WASI 0.3 introduit un modèle async natif qui se mappe directement sur les primitives async au niveau du langage :
- Rust :
async fnavectokioouasync-stdcompile nativement en async WASI 0.3 - Go : les goroutines se mappent sur les tâches async WASI
- Python : la boucle d’événements
asyncios’intègre au scheduler WASI - JavaScript :
Promiseetasync/awaitfonctionnent directement via JCO
Le runtime (Wasmtime, WasmEdge ou Spin) gère la boucle d’événements. Votre code écrit de l’async idiomatique dans le langage de votre choix, et la couche WASI s’occupe du reste.
// Handler HTTP async Rust compilé en WASI 0.3
use wasi::http::types::{IncomingRequest, ResponseOutparam};
async fn handle_request(req: IncomingRequest, resp: ResponseOutparam) {
// Lecture asynchrone du corps de la requête
let body = req.consume().await.unwrap();
let bytes = body.read_all().await.unwrap();
// Appel HTTP sortant (non-bloquant)
let api_response = wasi::http::outgoing_handler::handle(
build_api_request(&bytes)
).await.unwrap();
// Streaming de la réponse
let out = resp.set(200, &headers);
out.body().write_all(&api_response.body()).await.unwrap();
}
Types stream
WASI 0.3 introduit stream<T> et future<T> comme types de première classe dans le système de types du Component Model. Cela signifie que les composants peuvent passer des données en streaming à travers les frontières de langages sans sérialisation :
// Définition d'interface WIT avec types stream
interface data-processor {
process: func(input: stream<list<u8>>) -> stream<record>;
record record {
id: u64,
payload: list<u8>,
timestamp: u64,
}
}
Cela permet de véritables pipelines de streaming où un parseur de données Rust alimente un modèle ML Python qui alimente un sérialiseur Go — le tout dans le même processus, communiquant via des streams zero-copy.
Support complet des sockets
WASI 0.3 fournit des API complètes pour les sockets TCP et UDP :
tcp::listenettcp::connectpour les sockets serveur et clientudp::bindetudp::send_to/udp::recv_frompour les protocoles datagramme- Terminaison TLS via
wasi:sockets/tls - Résolution DNS via
wasi:sockets/name-lookup
Cela signifie que les modules Wasm peuvent désormais implémenter des protocoles personnalisés, des drivers de base de données, des clients de files de messages et toute autre charge de travail dépendante du réseau.
Le Component Model : composition polyglotte
Le Component Model, stabilisé dans WASI 0.2 et affiné dans 0.3, est ce qui rend le Wasm côté serveur fondamentalement différent des conteneurs. Il permet de composer plusieurs composants Wasm — écrits dans différents langages — en une seule application :
+------------------+ +-------------------+ +------------------+
| Auth Component |---->| Business Logic |---->| Data Layer |
| (Rust) | | (Python) | | (Go) |
+------------------+ +-------------------+ +------------------+
| | |
wasi:http wasi:keyvalue wasi:sql
capability capability capability
Chaque composant :
- S’exécute dans son propre bac à sable avec une sécurité basée sur les capacités (pas d’autorité ambiante)
- Déclare les interfaces système nécessaires via WIT
- Communique avec les autres composants via des interfaces typées, pas du JSON sérialisé
- Peut être mis à jour indépendamment sans redéployer l’ensemble de l’application
Fermyon Spin 3.0, sorti en janvier 2026, supporte les applications multi-composants en production. Fastly Compute propose la composition de composants depuis fin 2025.
Performance : démarrages à froid en microsecondes vs secondes pour les conteneurs
La métrique clé qui rend le Wasm attractif pour le serverless est le temps de démarrage à froid :
| Métrique | Conteneur Docker | AWS Lambda | Module Wasm (Spin) | Module Wasm (Wasmtime) |
|---|---|---|---|---|
| Démarrage à froid | 500ms - 5s | 100ms - 2s | 0.5ms - 3ms | 0.3ms - 2ms |
| Invocation à chaud | 1ms - 50ms | 1ms - 20ms | 0.1ms - 1ms | 0.05ms - 0.5ms |
| Empreinte mémoire | 50MB - 500MB | 128MB - 10GB | 1MB - 20MB | 1MB - 15MB |
| Taille du binaire | 50MB - 2GB | N/A (package zip) | 1MB - 30MB | 1MB - 30MB |
| Surcharge au démarrage | OS + runtime + app | Runtime + app | Instanciation module | Instanciation module |
| Isolation | Linux namespaces + cgroups | Firecracker microVM | Bac à sable Wasm | Bac à sable Wasm |
La différence n’est pas incrémentale — c’est trois ordres de grandeur. Un démarrage à froid Wasm mesuré en microsecondes contre des secondes pour un conteneur signifie que vous pouvez passer à zéro sans vous soucier de la latence côté utilisateur.
Pourquoi si rapide ?
Les modules Wasm sautent toute la séquence de démarrage de l’OS. Pas d’initialisation du noyau, pas de montage du système de fichiers, pas de chargement de bibliothèques dynamiques. Le runtime pré-compile le bytecode Wasm en code machine natif (compilation AOT), et l’instanciation est simplement l’allocation d’une région de mémoire linéaire et l’initialisation des variables globales.
Wasmtime 19 (mars 2026) a introduit l’allocation d’instances en pool, qui pré-alloue un pool de slots mémoire. L’instanciation d’un nouveau module Wasm devient un simple décalage de pointeur — littéralement des nanosecondes.
Paysage des fournisseurs cloud
Chaque grand fournisseur cloud propose désormais du Wasm serverless :
AWS Lambda Wasm Runtime (GA décembre 2025)
- Support WASI 0.3 via Wasmtime
- Démarrages à froid sub-milliseconde
- Support du Component Model pour les fonctions multi-langages
- Intégration avec API Gateway, S3 events, SQS triggers
- Prix : 50% moins cher que le Lambda conteneur équivalent
Google Cloud Run Wasm (GA février 2026)
- Déploiement de composants
.wasmdirectement viagcloud run deploy --wasm - Auto-scaling à zéro avec démarrages à froid en microsecondes
- Support gRPC et HTTP/2 via les sockets WASI
- Intégration avec Pub/Sub, Cloud Storage, BigQuery
Azure Container Apps Wasm (Preview, GA Q2 2026)
- Kubernetes-natif : charges de travail Wasm et conteneurs côte à côte
- Spin Operator gère le cycle de vie des composants Wasm
- Auto-scaling basé sur KEDA avec réponse sub-seconde
Fournisseurs edge
Cloudflare Workers supporte Wasm depuis 2018 et a pleinement adopté WASI 0.3 en janvier 2026. Fastly Compute exécute toutes les charges de travail comme composants Wasm. Vercel Edge Functions a ajouté le support Wasm fin 2025.
Workflow de développement Rust + Wasm
Rust reste le langage le mieux supporté pour le développement Wasm grâce à son overhead runtime nul et sa cible wasm32-wasip2 de première classe.
Configuration du projet
# Installer la cible WASI
rustup target add wasm32-wasip2
# Créer un nouveau projet
cargo init --name my-service
# Ajouter les dépendances WASI
cargo add wit-bindgen
cargo add wasi --features "http,keyvalue,sql"
Build et tests
# Build du composant Wasm
cargo build --target wasm32-wasip2 --release
# Exécution locale avec Wasmtime
wasmtime serve target/wasm32-wasip2/release/my_service.wasm
# Ou avec Spin
spin build && spin up
# Exécution des tests
cargo test --target wasm32-wasip2
Conteneurs vs Modules Wasm : comparaison complète
| Dimension | Conteneurs (Docker/OCI) | Modules Wasm (WASI 0.3) |
|---|---|---|
| Démarrage à froid | 500ms - 5s | 0.3ms - 3ms |
| Surcharge mémoire | 50MB - 500MB baseline | 1MB - 20MB baseline |
| Taille binaire | 50MB - 2GB images | 1MB - 30MB composants |
| Modèle d’isolation | Linux namespaces + cgroups | Bac à sable Wasm (memory-safe by design) |
| Support langages | Tous (binaires natifs) | Rust, Go, Python, JS, C/C++, C#, Kotlin |
| Réseau | Stack réseau OS complète | Sockets WASI (TCP, UDP, TLS) |
| Système de fichiers | Système de fichiers POSIX complet | FS virtuel basé sur les capacités |
| Accès GPU | NVIDIA Container Toolkit | Expérimental (wasi-nn) |
| Maturité écosystème | 12+ ans, écosystème massif | 3 ans, croissance rapide |
| Orchestration | Kubernetes, ECS, Nomad | SpinKube, wasmCloud, Kubernetes (via shim) |
Quand utiliser Wasm
- Fonctions serverless — quand la latence de démarrage à froid compte
- Edge computing — quand la taille du binaire et la mémoire sont contraintes
- Systèmes de plugins — quand vous avez besoin d’exécution sécurisée de code tiers
- Plateformes multi-locataires — quand la densité d’isolation compte
- Microservices polyglottes — quand les équipes utilisent différents langages
Quand rester sur les conteneurs
- Charges GPU (entraînement/inférence ML) — le support GPU WASI est encore expérimental
- Applications legacy dépendant de fonctionnalités OS spécifiques
- Services avec état nécessitant un stockage local persistant
- Scénarios de débogage complexes nécessitant des outils OS complets
Études de cas en production
Shopify : commerce edge
Shopify a migré le rendu de ses vitrines vers Wasm à l’edge en 2025, traitant 2,3 millions de requêtes par seconde sur Cloudflare Workers. Résultat : réduction de 68% du TTFB pour les clients mondiaux.
Midokura (Sony) : passerelle IoT
La filiale de Sony Midokura utilise Wasm pour exécuter des handlers de protocoles d’appareils sur des passerelles IoT avec 256MB de RAM. Avec Wasm, ils exécutent 40 handlers de protocoles dans l’empreinte mémoire qui ne supportait que 4 conteneurs.
Fermyon Platform : SaaS multi-locataires
La plateforme cloud de Fermyon exécute les charges clients comme composants Wasm avec 12 000 instances par nœud. Démarrage à froid moyen de 0,8ms, coût par requête 10x inférieur aux fonctions Lambda équivalentes.
Modèle de sécurité
- Refus par défaut — un module Wasm ne peut accéder à rien sauf si l’hôte accorde explicitement des capacités
- Sécurité mémoire — la mémoire linéaire empêche les débordements de buffer de s’échapper du bac à sable
- Pas d’autorité ambiante — contrairement aux conteneurs, chaque capacité doit être accordée individuellement
- Vérification formelle — la spec Wasm est suffisamment simple pour les outils de vérification formelle
Questions fréquentes
WASI 0.3 est-il prêt pour la production ?
Oui. WASI 0.3 est la première version que la Bytecode Alliance considère prête pour la production pour les charges serveur.
Wasm peut-il remplacer Kubernetes ?
Pas entièrement. Wasm remplace le runtime conteneur pour les charges appropriées, mais l’orchestration reste nécessaire.
Qu’en est-il des drivers de base de données ?
Le support complet des sockets de WASI 0.3 permet aux drivers de base de données natifs de fonctionner. L’interface wasi:sql fournit une API SQL standardisée.
Comment WASI 0.3 gère-t-il l’état ?
Les modules Wasm sont sans état par défaut. Pour l’état, utilisez wasi:keyvalue, wasi:sql ou des services externes via les sockets WASI.
Quelle est la courbe d’apprentissage pour Rust + Wasm ?
Si vous connaissez déjà Rust, l’apprentissage supplémentaire est minimal. Si Rust est nouveau pour vous, comptez 2-4 semaines pour devenir productif.