> we contributed upstream to ensure these HTTP clients can route requests directly through the JavaScript `fetch` API in WebAssembly environments
Some context from an urllib3 maintainer:
urllib3 received and merged large contributions adding Pyodide/Emscripten support a few years ago, and later JSPI support, which is what made this work for Requests.
As far as I know, the funding for this work went to the external contributor who implemented it, not to the urllib3 maintainers. We reviewed and merged the changes, and the project is now responsible for maintaining the resulting backend.
This matters because the Emscripten backend is still considered experimental in urllib3, and is explicitly out of scope in our security policy.
CVE-2025-50182 is one example of the problems we've run into. urllib3's redirect controls did not have the expected behavior when requests were routed through `fetch`. There are potentially many more differences like this because browser/`fetch` networking semantics are quite different from urllib3's normal backend.
I'm glad the work was contributed upstream and is useful to Pyodide and Cloudflare. But I think there is a meaningful difference between funding a contribution to an upstream project and funding the upstream maintainers who have to support it afterwards.
It always seemed so strange to me that "native" http clients were so lousy or many cases even non-existent considering that that's half of development these days.
I was very excited when they first launched Python Workers two years ago. Even though we have competing products at Wasmer, I think Cloudflare work is always exciting and inspiring.
I went back to the feedback I posted in the original launch thread [1]. It's great to see that they have made meaningful progress since then, particularly around package support: PyEmscripten is now standardized through PEP 783.
That said, some of the main architectural concerns I raised at the time are still present:
* Being tied to use only one version of Python/Pyodide (the one that Workerd embeds)
* Architecturally tied to the JS/v8 world, which may show some challenges as they aim to reduce cold start times (in my opinion, it will be quite hard for them to achieve <100ms startup time with their current architecture).
In the benchmark we published earlier this year [2], a minimal Python application started in around 60ms on Wasmer Edge versus around 900ms on Cloudflare Workers (backing my concerns from 2024). Those numbers are now several months old, and I hope Cloudflare has improved them significantly since then.
The GA announcement doesn't seem to include updated cold-start numbers. Could someone from the Cloudflare team share the current p50/p95 cold-start times for Python Workers, ideally both with and without native user packages? (for example, one with FastAPI and other without any dependencies).
> Being tied to use only one version of Python/Pyodide (the one that Workerd embeds)
This isn't quite the case, you can choose between different versions using compatibility flags. For example, `python_workers_314` is the compat flag for Python 3.14[1]. You've also got compat flags for 3.13 and 3.12. Though it is worth noting that by using those older versions you will also be using older Pyodide versions too, which have fewer features (for example they lack JSPI support).
> Architecturally tied to the JS/v8 world, which may show some challenges as they aim to reduce cold start times
That is indeed a challenge. But our memory snapshot implementation has improved the cold starts significantly already and we will be working to reduce these even further. We also have sharding these days which reduces cold start frequency a lot. We wrote about cold starts (and sharding) in a previous blog post[2] which includes some numbers.
> it is worth noting that by using those older versions you will also be using older Pyodide versions too
Yeah, I think this summarizes properly the issue I mentioned. Basically compat flags are a global version that affects not only the Python version used but workerd as well. I believe you'll see some architectural issues from this design. Following up on your example, users will not be able to use a previous version of Python that has JSPI included, unless you update the old workerd as well (please correct me if I'm wrong), which will make certain things a challenge as workerd evolves.
> We wrote about cold starts (and sharding) in a previous blog post[2] which includes some numbers
Thanks for sharing. On that blogpost [2] Cloudflare Python Workers startup time was reported to be about 1.027 seconds, which is way behind the numbers we have at Wasmer for cold starts in Python apps (60ms, or 16x faster). That's why I was asking if you guys remeasured and have better timings now :)
This is the tech at Cloudflare of course, but I swear that my first interpretation of the title was "We have replaced all our python coders with AI and they (the coders) are out and generally available" :-)
How do these perform for cold-starts? I remember one of the disadvantages of using web assembly for Workers was more spin-up time, but maybe they figured out a way around that.
The cold start numbers on that blog post show that its faster than AWS Lambda but your linked benchmark page [1] shows that Lambda is not only much faster but also much more consistent.
In many cases, the cold-start time might not be visible to users. E.g. if you serve your static content from a CDN, maybe you have stale content in local storage you can show while fetching updated data. If it all happens on a sub-100ms timescale, it should feel quite instant?
Gyeongjae, who is one of the authors too, is also a Pyodide core developer. Definitely couldn't have got Python Workers this far without both of their help.
Some context from an urllib3 maintainer:
urllib3 received and merged large contributions adding Pyodide/Emscripten support a few years ago, and later JSPI support, which is what made this work for Requests.
As far as I know, the funding for this work went to the external contributor who implemented it, not to the urllib3 maintainers. We reviewed and merged the changes, and the project is now responsible for maintaining the resulting backend.
This matters because the Emscripten backend is still considered experimental in urllib3, and is explicitly out of scope in our security policy.
CVE-2025-50182 is one example of the problems we've run into. urllib3's redirect controls did not have the expected behavior when requests were routed through `fetch`. There are potentially many more differences like this because browser/`fetch` networking semantics are quite different from urllib3's normal backend.
I'm glad the work was contributed upstream and is useful to Pyodide and Cloudflare. But I think there is a meaningful difference between funding a contribution to an upstream project and funding the upstream maintainers who have to support it afterwards.
I was very excited when they first launched Python Workers two years ago. Even though we have competing products at Wasmer, I think Cloudflare work is always exciting and inspiring.
I went back to the feedback I posted in the original launch thread [1]. It's great to see that they have made meaningful progress since then, particularly around package support: PyEmscripten is now standardized through PEP 783.
That said, some of the main architectural concerns I raised at the time are still present:
In the benchmark we published earlier this year [2], a minimal Python application started in around 60ms on Wasmer Edge versus around 900ms on Cloudflare Workers (backing my concerns from 2024). Those numbers are now several months old, and I hope Cloudflare has improved them significantly since then.The GA announcement doesn't seem to include updated cold-start numbers. Could someone from the Cloudflare team share the current p50/p95 cold-start times for Python Workers, ideally both with and without native user packages? (for example, one with FastAPI and other without any dependencies).
[1] https://news.ycombinator.com/item?id=39907120
[2] https://wasmer.io/posts/wasm-clouds-the-world-after-containe...
> Being tied to use only one version of Python/Pyodide (the one that Workerd embeds)
This isn't quite the case, you can choose between different versions using compatibility flags. For example, `python_workers_314` is the compat flag for Python 3.14[1]. You've also got compat flags for 3.13 and 3.12. Though it is worth noting that by using those older versions you will also be using older Pyodide versions too, which have fewer features (for example they lack JSPI support).
> Architecturally tied to the JS/v8 world, which may show some challenges as they aim to reduce cold start times
That is indeed a challenge. But our memory snapshot implementation has improved the cold starts significantly already and we will be working to reduce these even further. We also have sharding these days which reduces cold start frequency a lot. We wrote about cold starts (and sharding) in a previous blog post[2] which includes some numbers.
1 - https://developers.cloudflare.com/workers/configuration/comp...
2 - https://blog.cloudflare.com/python-workers-advancements/
> it is worth noting that by using those older versions you will also be using older Pyodide versions too
Yeah, I think this summarizes properly the issue I mentioned. Basically compat flags are a global version that affects not only the Python version used but workerd as well. I believe you'll see some architectural issues from this design. Following up on your example, users will not be able to use a previous version of Python that has JSPI included, unless you update the old workerd as well (please correct me if I'm wrong), which will make certain things a challenge as workerd evolves.
> We wrote about cold starts (and sharding) in a previous blog post[2] which includes some numbers
Thanks for sharing. On that blogpost [2] Cloudflare Python Workers startup time was reported to be about 1.027 seconds, which is way behind the numbers we have at Wasmer for cold starts in Python apps (60ms, or 16x faster). That's why I was asking if you guys remeasured and have better timings now :)
There is still more to do here and it’s what we will be focusing on next.
[1] https://cold.picheta.me/#bare
[1] https://news.ycombinator.com/item?id=48642510
[2] https://news.ycombinator.com/item?id=46557825
Still a welcome move that they finally added support from Python.