Cloudflare ajoute le profiling CPU et mémoire à la demande pour Workers et Durable Objects
Le 9 octobre 2026, Cloudflare généralise le profiling CPU et mémoire à la demande pour Workers et Durable Objects, avec des flamegraphs interactifs générés directement en production. Utilisez-le pour traquer les fuites mémoire et les fonctions les plus gourmandes, au lieu de deviner à partir de logs et de métriques agrégées.
9 octobre 2026. Cloudflare annonce le support du profiling CPU et mémoire pour Workers et Durable Objects. 128 Mo. C’est la limite mémoire par Worker, qu’un exemple interne a frôlé à 133 Mo au P999. 2,7×. C’est l’accélération obtenue par l’équipe R2 après avoir éliminé un parcours d’arbre redondant repéré dans un flamegraph. Pourquoi c’est important : les logs et les métriques agrégées ne disent pas quelle fonction consomme vos cycles ou alloue votre mémoire — le profiling en production, si.
Pourquoi profiler en production plutôt qu’en local
Comprendre pourquoi une application consomme plus de CPU ou de mémoire que prévu est l’un des problèmes les plus frustrants du serverless. Les logs racontent ce qui s’est passé, pas où le temps a été perdu. Les métriques agrégées donnent une tendance, pas une cause. Le profiling apporte la réponse précise : il montre la fonction exacte où votre code consomme du CPU ou alloue de la mémoire.
Cloudflare supportait déjà le profiling local via Chrome DevTools, mais jamais sur des Workers en production. Or, profiler en local a une limite structurelle : un Worker local ne reçoit ni le même type ni le même volume de requêtes qu’en production. Le meilleur moyen de comprendre une application, c’est de la profiler là où elle tourne réellement.
La nouveauté, c’est le profiling à la demande sur des Workers actifs. Depuis la page Observability d’un Worker, vous pouvez demander un profil CPU ou mémoire, l’inspecter sous forme de flamegraph interactif, puis télécharger le fichier de profil pour une analyse plus poussée.
Comment lancer un profil
Deux chemins mènent au profil. En ligne de commande, avec l’outil cf :
cf workers versions profile latest \
--worker-id "$WORKER_ID_OR_NAME" \
--profile-type cpu > worker-cpu.pprof Ou via le tableau de bord : Build → Compute → Workers & Pages, sélectionnez votre Worker, ouvrez l’onglet Observability, puis choisissez « Flamegraph ». Vous choisissez alors la durée du profil et la version du Worker à profiler. Attention : le Worker doit recevoir suffisamment de trafic pour être profilé — choisissez une version réellement déployée.
Dans un flamegraph, chaque rectangle représente un appel de fonction, et sa largeur représente la part de temps CPU ou de mémoire consommée par cette fonction. Cliquez sur une fonction pour zoomer, survolez pour voir le détail. La vue tableau complète le flamegraph en triant les fonctions par nombre d’échantillons. Si votre Worker est en TypeScript, activez les source maps — sinon le profil affichera des noms de fonctions obfusqués, illisibles.
Le fichier téléchargé est un profil pprof, le format ouvert popularisé par Google. Vous pouvez le rouvrir avec l’outil pprof en local, ou dans tout visualiseur compatible comme Grafana Pyroscope, pour croiser un flamegraph Cloudflare avec vos tableaux de bord existants. C’est ce qui sépare ce profiling d’un gadget visuel : il s’intègre à une chaîne d’observabilité au lieu de rester enfermé dans la console du fournisseur.
Un gain de 2,7× obtenu en une lecture
L’exemple le plus parlant vient de l’équipe R2, qui a profilé le Worker implémentant la liaison R2. Un profil CPU de 50 secondes a mis en évidence deux points chauds. Le premier : une fonction de remplacement (genericR2JsonReplacer) qui s’appelait récursivement. Appelée par JSON.stringify sur chaque nœud de l’arbre JSON, elle re-parcourait aussi l’arbre elle-même — un nœud imbriqué sur cinq niveaux était donc traité cinq fois. La correction a rendu la fonction 2,7× plus rapide.
Le second point chaud était plus discret : un appel dupliqué à une fonction de métriques, suffisamment lourd pour représenter 1 % du temps CPU à lui seul. Stocker le résultat du premier appel dans une variable au lieu de rappeler la fonction a libéré une part de temps non négligeable.
Le cas mémoire est tout aussi instructif. Un Worker interne voyait son P999 de mémoire osciller autour de 133 Mo, contre une limite de 128 Mo, provoquant des évictions fréquentes en erreur « Exceeded Memory ». Un profil de tas ouvert avec pprof a montré qu’un code Prometheus, censé être désactivé, représentait 66,7 % des allocations. Il instrumentait une grande partie des chemins de code du Worker, consommant sa mémoire alors même que les données collectées ne quittaient jamais le Worker. La suppression complète de ce code a ramené le P999 à environ 10 Mo sous la limite.
Pour un SRE, cela change le flux de débogage. Au lieu de reproduire une fuite mémoire en local — souvent impossible quand la fuite dépend du trafic de production — on capture un profil de tas sur l’isolat vivant et on lit directement la pile d’allocation. Au lieu de fixer un graphe CPU qui dit seulement « le Worker est lent », on ouvre le flamegraph et on voit quelle fonction est large. Les exemples de Cloudflare sont instructifs parce qu’ils ont été trouvés dans du code que personne ne soupçonnait : une fonction de remplacement qui re-parcourait un arbre dans lequel elle était déjà, et une instrumentation Prometheus prétendument désactivée qui allouait toujours.
La mécanique sous le capot
Profiler un Worker en production pose un problème que le profiling local ignore. Les Workers sont répliqués sur plusieurs centres de données et plusieurs machines physiques ; un Worker très sollicité peut être répliqué plusieurs fois sur une même machine. Les Durable Objects ajoutent une couche d’indirection supplémentaire : ils sont déplaçables dynamiquement. Avant de démarrer un profil, il faut donc répondre à plusieurs questions — quelle version profiler, dans quel centre de données cette version a-t-elle tourné récemment, l’isolat appartient-il bien au compte demandeur, et pour un Durable Object, où se trouve l’acteur principal actif.
La contrainte clé est de ne pas interrompre le Worker pendant la collecte. Un profil ne sert que si l’application continue de s’exécuter. Le runtime ne tient donc le verrou de l’isolat que pour les opérations du cycle de vie du profiler : il acquiert le verrou, démarre un profiler V8 avec un échantillonnage à 1 ms, relâche le verrou le temps de la collecte, puis le reprend pour arrêter le profiling et sérialiser le résultat hors section critique. Tenir le verrou pendant toute la durée bloquerait l’exécution JavaScript et rendrait le profil inutilisable.
Les Durable Objects bénéficient d’un avantage propre : étant stateful et nommés, on peut demander le profil d’un objet précis, n’importe où dans le monde. Le runtime route alors la requête vers la machine qui possède l’acteur et renvoie le profil de l’isolat exact.
Ce que ça ne fait pas encore
Le profiling à la demande a deux limites assumées. D’abord, il faut démarrer explicitement la session : vous pouvez manquer la fenêtre où le Worker se comporte mal. Ensuite, le profiler mémoire ne voit que les allocations pendant la fenêtre de profiling — un Worker qui alloue massivement au démarrage n’apparaîtra pas.
Cloudflare annonce déjà travailler sur le profiling continu : capturer des échantillons automatiquement pour explorer les profils directement dans le tableau de bord, et saisir les événements rares qu’une capture manuelle laisse passer.
Verdict
Si vous opérez des Workers ou des Durable Objects qui frôlent la limite de 128 Mo ou dont la latence dérive, activez le profiling dès aujourd’hui : un seul profil de 50 secondes a suffi à l’équipe R2 pour un gain de 2,7×, et le cas mémoire interne a trouvé sa cause en une lecture. Si vos Workers sont en TypeScript, commencez par activer les source maps, faute de quoi vos flamegraphs resteront illisibles. Si vous n’êtes pas sur Cloudflare, retenez la méthode plutôt que l’outil : profiler en production — et non en local — est la seule façon de voir les vrais points chauds, et les gains se chiffrent en facteurs multiplicatifs, pas en micro-optimisations.