Backend Engineering

Stop Ignoring Cloudflare Python Workers in 2026

Cloudflare Python Workers hit GA in 2026. No more JS glue code, FastAPI and Django now work, and Postgres runs at the edge. Here's what actually changed.

M
Md Shayon
Sep 22, 2026
7 min read
Table of Contents
Stop Ignoring Cloudflare Python Workers in 2026

So you looked at Cloudflare Python Workers a while back, probably during the beta, and thought "nah, too much hassle." Fair. It was rough.

That's changed. In September 2026 Cloudflare pushed Python Workers to GA. General availability. Python is now a real, fully supported language on their platform, not some experiment sitting in the corner next to TypeScript.

If you wrote it off, this is probably the point where you should look again.

What GA Actually Gets You

GA sounds like marketing fluff. It's not, in this case. It means Python Workers can now talk to Cloudflare stuff natively. Workers AI, R2, D1, Hyperdrive, Durable Objects, Queues, Workflows. All of it. No JavaScript required.

Here's the thing that used to annoy everyone. Sending a Python dict into a Queue looked like this:

from pyodide.ffi import to_js
import js

self.env.QUEUE.send(to_js({"key": "value"}, dict_converter=js.Object.fromEntries))

Yeah. Now it looks like this:

self.env.QUEUE.send({"key": "value"})

Cloudflare themselves called the old way "a common source of error for both humans and AI agents." Read that again. Even the AI tools were messing it up. That's how bad it was.

Learning Next.js in 2026

FastAPI, Django, Flask, No Server Needed

This is the part most people care about. You can now run FastAPI, Django, or Flask inside a Python Worker. No Uvicorn. No Gunicorn. No config files with threads and workers.

A FastAPI app that normally needs a server just gets one extra line:

from fastapi import FastAPI
from workers import asgi, WorkerEntrypoint

app = FastAPI()

@app.get("/")
async def root(request):
    env = request.scope["env"]
    return await env.AI.run(
        "@cf/openai/gpt-oss-120b",
        {
            "instructions": "You are a friendly assistant.",
            "input": "What is the origin of the phrase Hello, World?",
        },
    )

Default = asgi.entrypoint(app)

Django is similar but uses the WSGI version:

from workers import WorkerEntrypoint, wsgi
from your_django_app.wsgi import app

Default = wsgi.entrypoint(app)

Now, why does this work without a server? Because Cloudflare is the server. Their network already handles the load balancing and scaling. The workers.asgi and workers.wsgi connectors are just a thin layer. Request comes in as JavaScript, gets translated into what your framework expects, response goes back out.

Any framework that speaks ASGI or WSGI works. Not just those three.


Learn How to Build a TDD Workflow

The Database Thing (This One's Actually Cool)

Here's where it gets technical. Skip ahead if you want, but this part is interesting.

Python database drivers like asyncpg and aiomysql use the standard library's socket module. That module makes system calls to the OS. But inside WebAssembly, those syscalls are stubs. They just fail. So for the longest time, Python Workers literally could not connect to a database. At all.

Cloudflare fixed it by implementing the socket syscalls themselves. They translate Python socket calls into Workers connect API calls. Your drivers don't know anything changed. They just work:

import aiomysql
from workers import WorkerEntrypoint

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        hd = self.env.HYPERDRIVE_MYSQL
        conn = await aiomysql.connect(
            host=hd.host,
            port=int(hd.port),
            user=hd.user,
            password=hd.password,
            db=hd.database,
            ssl=None,
        )

        cur = await conn.cursor()
        await cur.execute("SELECT username FROM user")
        r = await cur.fetchall()
        await cur.close()
        conn.close()

Set the binding in Wrangler:

"hyperdrive": [
    {
        "binding": "HYPERDRIVE_MYSQL",
        "id": "<example id: 57b7076f58be42419276f058a8968187>",
    }
]

Done. Postgres and MySQL both work through Hyperdrive.


Guide on Switching From SQL to MongoDB

PEP 783: The Boring Part That Actually Matters

This one sounds boring. It's not.

Any Python package with C, C++, or Rust extensions needs to be compiled to WebAssembly to run in a Python Worker. Before this, there was no standard way to do that. So Cloudflare's team manually compiled and hosted packages themselves. One by one. That doesn't scale, and it means you could only use whatever they'd bothered to build.

So they proposed PEP 783. It creates a standard called "PyEmscripten" for running Python in WebAssembly environments. Took over a year of discussion. It got accepted.

They also added PyEmscripten support to cibuildwheel, which is what a lot of the Python packaging world already uses to build wheels for different platforms.

What does this mean for you? Once maintainers start using it, you can just pip install a package with native extensions and it'll have a WebAssembly wheel ready. Not a Cloudflare-specific thing either. Any platform that implements PyEmscripten can use it.

It's early. A lot of packages don't have these wheels yet. But this is the kind of thing that quietly fixes a whole category of problems down the road.

AI Agents Run Natively Now

If you're building agents in 2026, pay attention here.

openai and langchain use HTTP clients like requests and httpx under the hood. Those need real socket networking. Which, you know, didn't exist in Python Workers before. So they just didn't work.

Cloudflare fixed this upstream. Those HTTP clients now route through JavaScript's fetch API inside WebAssembly. Combined with the socket support, openai, langchain, and mcp all run natively now.

Here's a LangChain example hitting Workers AI:

from langchain_cloudflare import ChatCloudflareWorkersAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from workers import Response, WorkerEntrypoint

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        prompt = PromptTemplate.from_template(
            "In one sentence, describe a great day in the life of an {profession}."
        )
        llm = ChatCloudflareWorkersAI(
            model_name="@cf/meta/llama-3.3-70b-instruct-fp8-fast",
            binding=self.env.AI,
            max_tokens=64,
        )
        chain = prompt | llm | StrOutputParser()

        result = await chain.ainvoke({"profession": "electrician"})
        return Response.json({"result": result})

Why this matters: you can run an MCP server, a RAG pipeline with Vectorize, or a whole LangChain agent chain entirely at the edge. No separate Python backend sitting somewhere. No servers to babysit.

Cloudflare has a repo called python-workers-examples with working code. There's an image generation pipeline (Queue → Workflows → Workers AI → R2) and a Bluesky Jetstream WebSocket consumer backed by a Durable Object.

How to Actually Get Started

The CLI is pywrangler. You need uv and Node installed first.

uvx --from workers-py pywrangler init

That makes a pyproject.toml and a Wrangler config. Then:

uv run pywrangler dev
uv run pywrangler deploy

A basic Worker is literally four lines:

from workers import WorkerEntrypoint, Response

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        return Response("Hello World!")

One thing to watch, you have to add the python_workers compatibility flag. Otherwise nothing works and you'll be confused for twenty minutes. Ask me how I know.

Some Honest Caveats

Not everything is perfect yet.

PyEmscripten adoption is early. Most packages don't have WebAssembly wheels yet. If something you need isn't supported, Cloudflare says to ping them on Discord or GitHub and they'll try to build it.

Performance and memory work is still ongoing. Cloudflare said so themselves. And there weren't any third-party benchmarks of cold-start times or Hyperdrive connection pooling available when the announcement dropped. So don't expect magic numbers yet.

Dynamic Python Workers (a Python Worker inside another Worker) is mentioned but not fully documented on isolation guarantees. If you're doing anything security-sensitive, check the docs first before trusting it.

Why This One's Different

Here's what I like about this release. Cloudflare didn't just build something for Cloudflare.

PEP 783 benefits the whole Pyodide and Python-on-WebAssembly community. Not just their platform. Compare that to how Vercel and Railway do things, where everything lives inside their own runtime.

The announcement put it well, the goal was never to make packages that only work in Python Workers. It was to let the ecosystem grow in a way that helps everyone running Python on WebAssembly.

That's the difference between a feature and a foundation. Features get deprecated. Foundations stick around.

So if you've been putting off Cloudflare Workers for your Python stuff, FastAPI, LangChain, Postgres, whatever, the reasons you had are mostly gone. The glue code is gone. The database problem is gone. The package lock-in is going away.

The beta is done. The excuses are too.

Tags

# Cloudflare Python Workers# Python serverless# FastAPI Cloudflare# Django serverless# Hyperdrive Postgres# PEP 783# Pyodide WebAssembly# LangChain edge# Workers AI# Python edge computing
Keep Reading

Related Articles

Continue your learning journey