Aller au contenu principal
DevOpsMar 28, 2026

WASI 0.3 et la mort des démarrages à froid : le Wasm côté serveur en production

OS
Open Soft Team

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 fn avec tokio ou async-std compile nativement en async WASI 0.3
  • Go : les goroutines se mappent sur les tâches async WASI
  • Python : la boucle d’événements asyncio s’intègre au scheduler WASI
  • JavaScript : Promise et async/await fonctionnent 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::listen et tcp::connect pour les sockets serveur et client
  • udp::bind et udp::send_to / udp::recv_from pour 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étriqueConteneur DockerAWS LambdaModule Wasm (Spin)Module Wasm (Wasmtime)
Démarrage à froid500ms - 5s100ms - 2s0.5ms - 3ms0.3ms - 2ms
Invocation à chaud1ms - 50ms1ms - 20ms0.1ms - 1ms0.05ms - 0.5ms
Empreinte mémoire50MB - 500MB128MB - 10GB1MB - 20MB1MB - 15MB
Taille du binaire50MB - 2GBN/A (package zip)1MB - 30MB1MB - 30MB
Surcharge au démarrageOS + runtime + appRuntime + appInstanciation moduleInstanciation module
IsolationLinux namespaces + cgroupsFirecracker microVMBac à sable WasmBac à 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 .wasm directement via gcloud 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

DimensionConteneurs (Docker/OCI)Modules Wasm (WASI 0.3)
Démarrage à froid500ms - 5s0.3ms - 3ms
Surcharge mémoire50MB - 500MB baseline1MB - 20MB baseline
Taille binaire50MB - 2GB images1MB - 30MB composants
Modèle d’isolationLinux namespaces + cgroupsBac à sable Wasm (memory-safe by design)
Support langagesTous (binaires natifs)Rust, Go, Python, JS, C/C++, C#, Kotlin
RéseauStack réseau OS complèteSockets WASI (TCP, UDP, TLS)
Système de fichiersSystème de fichiers POSIX completFS virtuel basé sur les capacités
Accès GPUNVIDIA Container ToolkitExpérimental (wasi-nn)
Maturité écosystème12+ ans, écosystème massif3 ans, croissance rapide
OrchestrationKubernetes, ECS, NomadSpinKube, 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.