Le 12 octobre 2026, AWS a ouvert Lambda à un modèle d'exécution qui lui manquait depuis sa création : un serveur HTTP standard, capable de traiter jusqu'à 128 requêtes à la fois et facturé au seul CPU réellement consommé. Les adaptateurs deviennent inutiles, mais l'endpoint créé par défaut est public et Paris ne figure pas parmi les régions de lancement. Découvrez comment déployer une application Node.js sur Lambda Web Functions et ce qu'il faut vérifier avant la production.
Depuis son lancement en 2014, AWS Lambda repose sur un contrat unique : une fonction reçoit un événement, le traite puis rend la main, et chaque environnement d’exécution ne traite qu’une invocation à la fois. Ce modèle convient parfaitement au traitement d’une file de messages ou de fichiers déposés dans S3, beaucoup moins à une application web. Pour servir une API Express ou un site Next.js depuis Lambda, il fallait jusqu’ici intercaler API Gateway ou une Function URL, traduire l’événement en requête HTTP avec un adaptateur comme serverless-http ou AWS Lambda Web Adapter, et payer chaque milliseconde passée à attendre la base de données.
Le 12 octobre 2026, AWS a modifié ce contrat en lançant Lambda Web Functions. Parmi les services que nous suivons pour les infrastructures de nos clients, c’est l’évolution de Lambda la plus structurante depuis plusieurs années, parce qu’elle change à la fois le modèle de programmation et le modèle de facturation.
Une Web Function exécute un serveur HTTP standard qui écoute sur un port, sans handler ni adaptateur. Chaque environnement traite plusieurs requêtes simultanées (64 par défaut, jusqu’à 128) et la facture porte sur le CPU actif, la mémoire consommée et le nombre de requêtes, et non plus sur le temps passé à attendre les entrées-sorties.
Lambda se divise en trois formes
Avec cette annonce, Lambda devient une famille de trois modèles d’exécution, tous isolés par Firecracker, la technologie de micro-VM open source sur laquelle repose le service :
| Forme | Unité de travail | Requêtes simultanées par environnement | Facturation |
|---|---|---|---|
| Event Functions | un événement (SQS, S3, EventBridge…) | une seule | durée totale × mémoire configurée |
| Web Functions | une requête HTTP | 64 par défaut, 128 au maximum | CPU actif + mémoire consommée + requêtes |
| MicroVMs | une session isolée et persistante | pilotée par l’application | vCPU + mémoire + snapshots |
Les fonctions Lambda existantes deviennent des Event Functions. Il s’agit d’un simple changement de nom, qui n’impose ni modification de code ni redéploiement. Les MicroVMs, lancées en juin 2026, ciblent l’exécution de code fourni par des utilisateurs ou généré par l’IA. Pour choisir entre ces trois modèles selon vos charges, nous avons détaillé les critères dans notre guide Lambda Event Functions, Web Functions ou MicroVMs : quel modèle choisir.
Un serveur plutôt qu’un handler
La différence se lit directement dans le code. Voici la même API Express, avant et après :
// Avant : Event Function derrière API Gateway, avec un adaptateur
const serverless = require('serverless-http');
const express = require('express');
const app = express();
app.get('/health', (req, res) => res.json({ ok: true }));
module.exports.handler = serverless(app);
// Après : Web Function, un serveur Express standard
const express = require('express');
const app = express();
app.get('/health', (req, res) => res.json({ ok: true }));
// Lambda fournit l'adresse d'écoute ; en local, repli sur localhost:3000
const [host, port] = (process.env.AWS_LAMBDA_HTTP_ENDPOINT || 'localhost:3000').split(':');
app.listen(port, host);
Ce que ça change :
- le code est identique sur le poste du développeur et sur Lambda :
node index.jssuffit pour lancer le serveur en local ; - le runtime charge
index.jsà la racine du package (la variableAWS_LAMBDA_NODEJS_ENTRYPOINTdésigne un autre point d’entrée) et attend que le serveur écoute surAWS_LAMBDA_HTTP_ENDPOINTdans un délai de 10 secondes ; - Next.js en mode standalone lit ses propres variables d’écoute : un
index.jsintermédiaire les renseigne à partir deAWS_LAMBDA_HTTP_ENDPOINTavant de démarrer le serveur.
La multi-concurrence a une contrepartie que les équipes habituées à Lambda doivent intégrer. Une Event Function ne traite qu’une invocation à la fois, si bien qu’une variable globale y contient sans risque l’état de la requête en cours. Dans une Web Function, des dizaines de requêtes partagent le même processus et la même boucle d’événements Node.js : un état stocké en global peut fuiter d’un utilisateur à l’autre, et un calcul synchrone lourd bloque toutes les requêtes de l’environnement. Le portage d’une fonction existante impose donc une revue de ce point, et le calcul intensif doit passer par worker_threads ou par une valeur réduite de maxConcurrencyPerEnvironment.
La facturation au CPU actif
Une Event Function est facturée sur sa durée totale multipliée par la mémoire configurée : une requête qui attend trois secondes la réponse d’un LLM coûte autant que trois secondes de calcul. Une Web Function sépare trois compteurs, publiés pour US East (Virginie du Nord) sur Arm :
| Compteur | Tarif |
|---|---|
| vCPU actif | 0,0000276944 $ par vCPU-seconde (environ 0,10 $ l’heure) |
| Mémoire consommée, sur toute la vie de l’environnement | 0,0000036667 $ par Go-seconde |
| Requêtes | 0,30 $ par million |
L’exemple de streaming LLM publié par AWS illustre l’écart : 5 millions de requêtes par mois, d’une durée de 3 secondes chacune dont 200 ms de CPU actif, servies par un environnement actif en permanence, reviennent à 33,94 $ en Web Function. La même charge sur une Event Function de 512 Mo en Arm représente 7,5 millions de Go-secondes, soit environ 101 $ selon notre calcul (au tarif Arm de 0,0000133334 $ par Go-seconde, premier palier US East, hors free tier).
L’écart se resserre en revanche sur les requêtes courtes, et peut même s’inverser : la requête coûte 0,30 $ le million contre 0,20 $ pour une Event Function, et la mémoire reste facturée pendant les temps morts entre deux requêtes. Le gain est donc structurel pour les charges dominées par l’attente (streaming de tokens, API qui appellent des services tiers lents) et marginal ailleurs.
Ce modèle n’est pas une invention d’AWS. Côté plateformes front-end, Vercel l’applique à ses fonctions Fluid compute depuis juin 2025 (0,128 $ l’heure de CPU actif en région Washington). Ces plateformes ont bâti une partie de leur différenciation sur cette efficacité, et AWS la propose désormais en natif, à un tarif de CPU actif inférieur. La comparaison s’arrête toutefois au modèle de facturation : une plateforme comme Vercel vend aussi les environnements de preview, le CDN et l’outillage de déploiement, qu’il faut assembler soi-même sur AWS.
Cloudflare Workers : le même tarif, la philosophie inverse
Le parallèle le plus instructif reste Cloudflare, qui facture ses Workers au temps CPU depuis septembre 2023 et se présentait alors comme la première plateforme serverless mondiale à le faire. Sur le papier, AWS s’aligne jusqu’au prix de la requête :
| Lambda Web Functions | Cloudflare Workers (plan payant) | |
|---|---|---|
| Requêtes | 0,30 $ par million | 0,30 $ par million, dont 10 millions incluses dans l’abonnement à 5 $ par mois |
| CPU | environ 0,10 $ l’heure de vCPU actif | 0,02 $ par million de ms CPU, soit environ 0,07 $ l’heure |
| Mémoire | facturée, 2 Go par environnement | non facturée, 128 Mo par isolate |
| Exécution | micro-VM Firecracker, Node.js 24 complet | isolate du runtime Workers, compatibilité Node.js partielle |
| Next.js | serveur standalone, sans adaptateur | adaptateur OpenNext |
| Implantation | cinq régions AWS, multi-région en option | l’ensemble du réseau Cloudflare |
Les deux offres convergent vers le même modèle économique en partant de directions opposées. Cloudflare a demandé au code de s’adapter à la plateforme : un isolate léger limité à 128 Mo, un runtime qui n’est pas Node.js et une couche de compatibilité dont certaines API restent partielles, en échange d’une exécution dans chacun de ses points de présence. AWS fait l’inverse et adapte la plateforme au code : un Node.js complet et 2 Go de mémoire, au prix d’une mémoire facturée et d’une présence limitée à cinq régions.
Le placement suit la même logique, en miroir. Cloudflare est parti de l’edge et a dû créer Smart Placement pour rapprocher l’exécution des bases de données centralisées, car un rendu exécuté près de l’utilisateur perd son avantage dès qu’il enchaîne les allers-retours vers une base située sur un autre continent. AWS part de la région, à côté de la base de données, et propose le multi-région en option. Le choix entre les deux revient donc à se demander ce qui limite votre application : la distance qui la sépare de ses utilisateurs, ou celle qui la sépare de ses données.
Déployer en une commande
# Application de démonstration, pour valider l'accès au service
aws lambda-web deploy --name hello-world --hello-world
# Déployer le répertoire de l'application
aws lambda-web deploy --name my-web-app --code ./my-app
# Lancer le serveur en local avec la variable que Lambda fournira
AWS_LAMBDA_HTTP_ENDPOINT=127.0.0.1:3000 node index.js
Ce que ça fait :
deployempaquette le code dans un bucket S3 versionné, crée un rôle d’exécution, la fonction et une première révision immuable, puis un endpoint nommédev(--endpoint-namepour un autre nom) et renvoie une URL HTTPS de la forme<domain-id>.<shard-id>.lambda-web.<region>.on.aws;- un nouveau
deploypublie une nouvelle révision, que l’endpointdev, en modeLatestRevision, sert automatiquement dès qu’elle est active ; dans un pipeline CI/CD, l’option--createévite la confirmation interactive ; - l’option
--regions us-east-1,eu-west-1,ap-northeast-1réplique le code dans plusieurs régions derrière une URL globale, avec un routage par latence assuré « au mieux ».
Les dépendances natives doivent être compilées pour Arm64 : un module construit pour x86_64 ne démarre pas dans l’environnement d’exécution.
Sécuriser l’endpoint : le réglage par défaut est public
C’est le point que l’annonce passe sous silence : aws lambda-web deploy crée par défaut un endpoint ApplicationManaged. Lambda n’y authentifie aucune requête, et toute personne qui connaît le domaine peut appeler l’application. Ce mode convient à un site public dont l’application gère elle-même l’authentification, à condition de le choisir en connaissance de cause.
Dès que vous placez CloudFront devant l’application (domaine personnalisé, AWS WAF, cache des contenus statiques), passez l’endpoint en IamAuth et associez-lui un origin access control (OAC) CloudFront de type lambda, avec le comportement de signature always-amz-auth :
# Endpoint de production authentifié par IAM dès le déploiement
aws lambda-web deploy --name my-web-app --code ./my-app \
--endpoint-name prod --auth-type IamAuth
# Autoriser uniquement votre distribution CloudFront (politique à adapter)
aws lambda-web put-resource-policy \
--resource-arn "arn:aws:lambda:eu-west-1:111122223333:web-function/my-web-app" \
--policy file://cloudfront-oac-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontOACAccess",
"Effect": "Allow",
"Principal": { "Service": "cloudfront.amazonaws.com" },
"Action": "lambda:InvokeWebFunctionEndpoint",
"Resource": "arn:aws:lambda:eu-west-1:111122223333:web-function/my-web-app/endpoint/prod",
"Condition": {
"StringEquals": {
"aws:SourceArn": "arn:aws:cloudfront::111122223333:distribution/<distribution-id>"
}
}
}
]
}
Ce que ça fait :
- CloudFront signe chaque requête vers l’origine, et seule la distribution désignée par
aws:SourceArnest autorisée à invoquer l’endpoint ; - un en-tête
Authorizationapplicatif (JWT, par exemple) parvient à votre code si la distribution est configurée pour le transmettre, Lambda ne retirant que les valeurs qui sont des signatures AWS ; - le domaine de l’endpoint demeure joignable sur Internet, mais toute requête non signée par un principal autorisé est refusée.
À l’échelle d’une AWS Organization, une SCP qui refuse lambda:CreateWebFunction, CreateWebFunctionEndpoint et UpdateWebFunctionEndpoint lorsque la clé de condition lambda:Request/WebFunctionAuthType vaut ApplicationManaged interdit les endpoints publics à l’ensemble des comptes. Ce garde-fou relève de la gestion des identités et des accès, et il vaut mieux le poser avant que les premières équipes ne déploient.
Canary, plafonds et protection des dépendances
# Canary : 90 % du trafic sur la révision en place, 10 % sur la nouvelle
aws lambda-web update-web-function-endpoint \
--function-name my-web-app \
--endpoint-name prod \
--auto-deployment-mode Disabled \
--revision-weights '[{"revisionId": "<revision-actuelle>", "weight": 90}, {"revisionId": "<nouvelle-revision>", "weight": 10}]'
# Plafonner le nombre d'environnements et le débit accepté, par région
aws lambda-web update-web-function-endpoint \
--function-name my-web-app \
--endpoint-name prod \
--scaling-config '{"maxEnvironments": 50}' \
--throttle-config '{"rateLimit": 800}'
Ce que ça fait :
--auto-deployment-mode Disabledempêche une nouvelle révision de recevoir le trafic dès sa publication, ce qui est le réglage recommandé en production pour un déploiement continu maîtrisé ;maxEnvironmentsborne le nombre d’environnements (2 vCPU chacun, sur un quota de compte de 2 000 vCPU par région) et donc la facture comme la pression exercée sur la base de données ;rateLimitrenvoie un HTTP 429 au-delà du débit fixé : les clients doivent réessayer avec un backoff exponentiel et une part d’aléa.
Les métriques fournies par le service ne portent pas de dimension par révision. Pour juger un canary, journalisez l’identifiant de révision dans vos logs applicatifs.
Les réserves avant la production
- Node.js uniquement : le seul runtime disponible est
nodejs24.xsur Arm64. Python, Java et .NET restent sur les Event Functions. - Pas de région Paris : le service est disponible en Virginie du Nord, Ohio, Oregon, Tokyo et Irlande. Pour une application dont les données doivent rester en France, la question est tranchée pour l’instant.
- Aucun environnement minimum : Lambda conserve une marge de capacité tant que le trafic circule, mais un endpoint inactif redescend à zéro et la requête suivante attend un démarrage à froid, dont AWS ne publie aucune mesure.
- Un gabarit fixe : chaque environnement dispose de 2 Go de mémoire et de 2 vCPU, avec un tas V8 de 1 024 Mo par défaut et un
/tmpde 512 Mo partagé entre les requêtes simultanées. - Un périmètre HTTP précis : HTTP/1.1 uniquement (HTTP/1.0 est rejeté), en-têtes limités à 128 Kio, délai d’expiration de 30 secondes par défaut, configurable jusqu’à 15 minutes. La documentation ne prévoit pas de WebSocket et retire l’en-tête
Upgrade; pour ce besoin, les MicroVMs ou API Gateway restent la voie indiquée. - Un arrêt bref : à la réduction de capacité, le processus reçoit un
SIGTERMet dispose d’une seconde pour se terminer proprement.
Avant : API Gateway, une Event Function et un adaptateur, une requête par environnement et chaque milliseconde d’attente facturée Après : un serveur Express standard, jusqu’à 128 requêtes par environnement, facturé au CPU actif et déployé en une commande
Les Event Functions restent le bon outil pour les traitements déclenchés par un événement, comme un message dans une file, un fichier déposé dans S3 ou une tâche planifiée. Pour une application web, en revanche, Lambda Web Functions permet enfin de déployer le serveur tel qu’il tourne en local, sans API Gateway ni adaptateur. Avant de migrer, il reste à vérifier que la contrainte Node.js, l’absence de Paris et les démarrages à froid après une période creuse sont compatibles avec votre application.
Références
- Announcing AWS Lambda Web Functions : l’annonce officielle sur le blog AWS
- Documentation Lambda Web Functions : concepts, scaling, cycle de vie et contrôle d’accès
- Tarification AWS Lambda : grilles et exemples chiffrés des trois formes
- Tarification Cloudflare Workers : requêtes, temps CPU et limites du plan payant
