Cloudflare Python Workersは、Cloudflare WorkersのサーバーレスランタイムでPythonのコードを動かす仕組みです。2年間のオープンベータを経て、2026年9月21日にCloudflare公式ブログで一般提供(GA)が発表されました。FastAPI・Django・Flaskをそのまま載せられ、D1やR2、Hyperdriveといったバインディングにも、JavaScriptを書かずにPythonから触れられるようになっています。国内での報道は9月24日前後ですが、一次情報の公開日は9月21日です。
この記事では、PyodideとV8 isolateで動く仕組みを押さえたうえで、pywranglerでFastAPIをデプロイする手順、Hyperdrive経由でデータベースへつなぐ設定、移植前に確かめておく制約、そして受託開発で採用するかどうかの線引きまでを扱います。Workers全体の料金や無料枠、JavaScript・TypeScriptを含む対応言語の比較は、Cloudflare Workersの対応言語・無料枠・料金をまとめた記事にまとめています。
まとめ:Cloudflare Python Workersを使う条件と見送る条件
結論から書きます。純Pythonか、WebAssembly向けにビルド済みのパッケージだけで組めるAPIなら、Python Workersへ載せる価値があります。一方、threadingやmultiprocessingに依存する処理、WebAssembly向けのwheelが無いネイティブ拡張を使う処理は、従来どおりコンテナやLambdaに残すほうが無難です。
- 中身:CPythonをWebAssemblyに移植したPyodideを、WorkersのV8 isolateの中で動かす
- GAで変わった点:バインディングの型変換が不要になり、ASGI・WSGIのコネクタ、TCPソケット、Hyperdriveに対応した
- 使い始め:uvとNode.jsを入れ、
pywranglerで作成・ローカル実行・デプロイまで進める - 起動:デプロイ時にメモリのスナップショットを取り、リクエスト時はそこから起動する
- 制約:threadingとmultiprocessingは機能せず、ファイルへの書き込みはisolateが消えると失われる
Python WorkersのPyodideとV8 isolateによる実行構造
公式の仕組み解説によると、PythonのWorkerはPyodideによって実行されます。PyodideはCPythonをWebAssemblyへコンパイルしたもので、WorkersはJavaScriptと同じV8 isolateの中にこのPyodideを注入し、Pythonコードを解釈させます。Linuxのプロセスやコンテナを起動するわけではありません。isolate単位で分離される構造そのものは、V8 Isolateの分離設計と起動時間を実測した記事で詳しく扱っています。
Pythonのバージョンは毎年8月に出て、対応するPyodideが約6か月後に続きます。新しい版はcompatibility flagの背後に置かれ、指定したcompatibility_date以降で有効になる仕組みです。各Python版のサポート期間は5年で、期限を過ぎてもWorkerは動き続けますが、セキュリティパッチは届かなくなるため、版の追従は運用計画に含めておく必要があります。
2026年9月21日のGAで変わった点とオープンベータとの違い
ベータ期間の大きな不便は、バインディングにPythonの値を渡すたびに、to_jsでJavaScriptのオブジェクトへ変換するコードを書く点でした。GAではこの変換がランタイムとSDK側へ吸収され、self.env.QUEUE.send({"key": "value"})のように辞書をそのまま渡せます。人もAIエージェントも書き損じやすかった箇所が消えた形です。
もう1つの変化はネットワークです。以前はTCPソケットが使えず、データベースドライバが動きませんでした。GAではソケットのシステムコールをWorkersのconnect APIへ置き換える実装が入り、asyncpgやaiomysqlが接続できるようになっています。requestsやhttpxもJavaScriptのfetchを経由して通信する修正が上流へ取り込まれ、openai・langchain・mcpといったライブラリが動くと発表されました。
デプロイ時のメモリスナップショットでコールドスタートを縮める構造
Pythonはパッケージのimportに時間がかかります。そこでpywrangler deployを実行すると、Cloudflareはエントリポイントとトップレベルのimportを先に実行し、WebAssemblyのリニアメモリをスナップショットとして保存します。リクエストが来たら、そのスナップショットを読み込んで起動する流れです。
2025年12月8日の公式ブログでは、fastapi・httpx・pydanticをimportする構成でスナップショット無しなら約10秒、有りなら約1秒と説明しています。同じ条件の平均コールドスタートはPython Workersが1.027秒、SnapStart無しのAWS Lambdaが2.502秒、Google Cloud Runが3.069秒でした。ただし計測したのはCloudflare自身で、LambdaのSnapStartは比較に含まれていません。自社の判断材料にするなら、後述の手順で自分のコードを測り直します。
pywranglerでPython Workerを作成してローカル実行・デプロイする手順
前提はuvとNode.jsの2つです。Python Workers用のCLIであるpywranglerは、PyPIではworkers-pyという名前で配布されており、内部でWranglerを呼び出します。パッケージ管理をuvに寄せる設計なので、uvに慣れていない場合は先に基本操作を確認しておくと手戻りが減ります。
uvとpywrangler initによる作成とwrangler.jsoncの設定
Python Workersのドキュメントに載っている初期化コマンドは次のとおりです。pyproject.tomlとWranglerの設定ファイルが生成され、workers-pyが開発用の依存に入ります。
# プロジェクトの雛形を作る(uvとNode.jsが前提)
uvx --from workers-py pywrangler init
# ローカルで起動(既定は http://localhost:8787/)
uv run pywrangler dev
# Cloudflareへデプロイ
uv run pywrangler deploy
設定で外せないのはcompatibility_flagsのpython_workersです。mainには.pyのファイルを指定します。依存はpyproject.tomlに書けば、デプロイ時に自動で同梱されます。
// wrangler.jsonc
{
"name": "my-fastapi-app",
"main": "src/main.py",
"compatibility_date": "2026-10-11",
"compatibility_flags": ["python_workers"]
}
# pyproject.toml
[project]
name = "my-fastapi-app"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = ["fastapi"]
[dependency-groups]
dev = ["workers-py", "workers-runtime-sdk"]
FastAPIをasgi.entrypointで載せてcurlで動作を確かめる
通常のFastAPIはUvicornのようなASGIサーバーの上で動かします。Python WorkersではWorkersのプラットフォーム自体がWebサーバーの役割を担うため、Uvicornは要りません。FastAPIのページの例では、アプリをasgi.entrypointへ渡すだけで済みます。
# src/main.py
from fastapi import FastAPI, Request
from workers import asgi
app = FastAPI()
@app.get("/")
async def root():
return {"Hello": "World"}
@app.get("/env")
async def env_check(request: Request):
# バインディングや環境変数は request.scope["env"] から取り出す
env = request.scope["env"]
return {"has_env": env is not None}
Default = asgi.entrypoint(app)
# 別の端末で確認
# curl http://localhost:8787/
# {"Hello":"World"}
ルーティングやバリデーションの書き方は通常のFastAPIと変わりません。async defとdefの使い分けなどFastAPI自体の基本はFastAPIを最短で動かす手順の記事で確認できます。Djangoのような同期型のアプリはworkers.wsgiのコネクタを使い、Default = wsgi.entrypoint(app)と書きます。
Hyperdrive経由でPostgreSQLとMySQLへPythonから接続する設定
Workersから既存のデータベースへ直接つなぐと、リクエストごとの接続確立が重くなります。Hyperdriveは接続プールとクエリキャッシュを受け持つ中継サービスで、GAによりPythonからも使えるようになりました。
2026-09-08以降の設定とasyncpg・aiomysqlの選択基準
HyperdriveのPython Workers向けページは、compatibility_dateを2026-09-08以降にするよう求めています。古い日付のまま既存プロジェクトにHyperdriveを足すと動かないため、最初に確認する項目です。検証済みドライバとして、PostgreSQLはasyncpg(推奨)・pg8000・psycopg、MySQLはaiomysql(推奨)・pymysqlが挙げられています。
# wrangler.jsonc に追記
"hyperdrive": [
{ "binding": "HYPERDRIVE", "id": "<HYPERDRIVE_CONFIG_ID>" }
]
# src/main.py(pyproject.toml の dependencies に "asyncpg" を追加)
import asyncpg
from workers import Response, WorkerEntrypoint
class Default(WorkerEntrypoint):
async def fetch(self, request):
hd = self.env.HYPERDRIVE
conn = await asyncpg.connect(
host=hd.host, port=int(hd.port), user=hd.user,
password=hd.password, database=hd.database, ssl=False,
)
try:
value = await conn.fetchval("SELECT 1")
return Response.json({"result": value})
finally:
await conn.close()
ソケット操作は内部で非同期に処理されるため、1つのリクエストが応答待ちの間も他のリクエストを並行して処理できます。ただし低レベルのソケット操作の一部は期待どおりに動かない場合があると書かれています。独自プロトコルのクライアントを持ち込む場合は、本番前に疎通を確かめてください。
threading非対応やパッケージなど移植前に確かめる制約
既存のPythonアプリを移すとき、つまずく箇所はおおむね決まっています。コードを書き換える前に、次の3点を依存関係とソースから洗い出しておくと、移せるかどうかの判断が早く付きます。
PyEmscripten向けwheelが無いネイティブ拡張パッケージの扱い
パッケージのページによると、使えるのは純Pythonのパッケージ、PyEmscripten向けにビルドされたwheel、Pyodideに同梱されたパッケージの3種類です。C・C++・Rustの拡張を含むパッケージは、WebAssembly向けにクロスコンパイルされていなければ動きません。
この状況を変えるため、Cloudflareはブラウザ系ランタイム向けのプラットフォームを定義するPEP 783を提案し、承認されました。ただしドキュメント自身が、WebAssembly向けのパッケージ対応はまだ初期段階だと認めています。移植の前に、依存ツリーのネイティブ拡張を一覧にし、それぞれにPyEmscripten向けのwheelがあるかを確かめるのが確実です。
threading・multiprocessingとファイル書き込みが効かない前提の設計
標準ライブラリのページでは、threadingとmultiprocessingはimportできても機能しないと明記されています。curses・dbm・fcntl・pwd・resource・tkinter・venvなどはそもそも使えません。重い処理をスレッドで並列化している既存コードは、asyncioへの書き換えか、Queuesで処理を分ける設計に変える必要があります。
ファイル操作はopen()やpathlibで普通に書けますが、保存先はisolateごとのメモリ上の領域で、isolateが消えると中身も失われます。別のisolateとも共有されません。アップロードされたファイルや生成物の保存は、R2やKV、Durable Objectsへ置く前提で設計します。
トップレベルの乱数生成と重い初期化によるデプロイ時の停止理由と制限値
スナップショットには、トップレベルで実行した結果がそのまま焼き込まれます。ここで乱数の種まで固定されると、全リクエストが同じ乱数列を返してしまうのが問題です。これを防ぐため、デプロイ時にトップレベルで乱数生成器を呼ぶとデプロイ自体がエラーで止まる仕組みになっていると公式ブログが説明しています。モジュール読み込み時にトークンやIDを生成しているコードは、ハンドラの中へ移してください。
Workersの制限ページの値も、Pythonでは効き方が変わります。グローバルスコープの実行は1秒以内、メモリはJavaScriptのヒープとWebAssemblyの割り当てを合わせてisolateあたり128MB、Workerのサイズは非圧縮で64MiBが上限です。Pythonのインタプリタ自体がWebAssemblyのメモリを使うため、大きな数値計算ライブラリを読み込む構成では128MBの余裕が想定より小さくなる点に注意が要ります。
コールドスタート1.027秒の公式値を自社の構成で測り直す観点
公式の1.027秒は、3つのパッケージをimportする条件での平均値です。実際の起動時間は、依存の数と、トップレベルで何を実行するかで変わります。採用を判断する前に、自分のアプリをデプロイし、新しい版を出した直後の初回応答と2回目以降の応答を分けて測っておくと、数字の比較ができます。
# デプロイ直後の初回と、続く数回の応答時間を比べる
URL="https://my-fastapi-app.example.workers.dev/"
for i in 1 2 3 4 5; do
curl -s -o /dev/null -w "%{http_code} %{time_starttransfer}\n" "$URL"
done
見るべきは、初回だけが極端に遅いか、全体が遅いかです。初回だけが遅いならスナップショットからの復元が効いており、トップレベルの処理を減らす余地を探します。全体が遅いなら、データベース接続や外部APIの待ちが原因である可能性が高く、検討の対象はHyperdriveの利用や処理の非同期化です。いずれも、無料プランのCPU時間は1リクエスト10ミリ秒が上限なので、ダッシュボードでCPU時間も合わせて確認しておくと有料プランが必要かを判断できます。
受託開発でPython Workersを採用する条件と見送る場面
ここからは判断です。速さだけで選ぶのではなく、既存の資産と制約が合うかで決めます。次の3条件がそろうなら、Python Workersで組んで構いません。
- 依存がWebAssemblyで動く:純Pythonか、PyEmscripten向けwheelかPyodide同梱で済み、ネイティブ拡張の追加ビルドが要らない
- 処理が短いAPIで完結する:スレッドを使わず、1リクエストの処理がWorkersのCPU時間とメモリの上限に収まる
- 状態を外へ出せる:ファイルや状態をR2・KV・D1・Durable Objects、またはHyperdrive経由の既存DBへ置ける
逆に、次のどちらかに当てはまる場合は見送ります。第一に、画像処理や機械学習の推論などで、WebAssembly向けのビルドが無いライブラリや大きなメモリを前提にしている処理です。第二に、スレッドや子プロセスで並列化された既存のバッチ処理で、書き換えの工数が移行の利点を上回る場合です。こうした処理は、コンテナやAWS Lambdaの仕組みとコールドスタート対策をまとめた記事で扱う構成のほうが素直に動きます。
TypeScript Workersや既存のAWS Lambdaと比べて選ぶ判断
WorkersでAPIを新規に作るなら、型定義とライブラリの充実度ではまだTypeScriptが先行しています。Pythonを選ぶ理由となるのは、既存のPythonコードや社内のPython人材、langchainなどPython側にしか無いライブラリを使いたいという事情です。Lambdaとの比較では、地域を選ばずに配置される点とスナップショットが無料で効く点がPython Workersの利点で、実行時間の長さと使えるパッケージの幅はLambdaが勝ります。
エッジとクラウドの役割分担は、APIを置く場所、データベースの位置、認証の通り道を一緒に決めないと破綻します。既存のAWSやGoogle Cloudの構成とCloudflareを組み合わせた設計を進めたい場合は、一創のインフラ構築(AWS・Google Cloud・Azure)で、配置の切り分けから相談できます。
よくある質問
Cloudflare Python Workersを検討するときによく出る疑問を、2026年10月時点の公式ドキュメントに沿って整理しました。
Python Workersは無料プランでも使えますか?
Workersの制限ページは、無料プランと有料プランの列で共通の上限を示しており、Python専用の除外は記載されていません。無料プランでは1リクエストあたりのCPU時間が10ミリ秒に制限されるため、検証は無料で始め、CPU時間の実測値を見てから有料プランへ移るかを決めるのが現実的です。料金の内訳は親記事で扱っています。
requestsやhttpxで外部APIを呼べますか?
呼べます。GA発表によると、requestsやhttpxなどのHTTPクライアントがWebAssembly環境ではJavaScriptのfetch APIを経由して通信するよう、上流へ修正が取り込まれました。これによりopenai・langchain・mcpといったライブラリも動くとされています。サブリクエストの回数には、無料プランで1回の実行あたり50回という上限がある点に注意してください。
NumPyやpandasは使えますか?
Pyodideに同梱されたパッケージは使えるとドキュメントに書かれており、数値計算系のライブラリはPyodide向けにビルドされたものが提供されてきました。ただしメモリはisolateあたり128MBで、インタプリタ自体の使用分も含まれます。大きなデータフレームを扱う処理はWorkersに向かないため、集計はデータベース側や別の実行基盤で済ませ、Workersは結果を返す役に留めるほうが安全です。
Djangoのアプリはそのまま移せますか?
WSGIのコネクタで起動はできますが、そのまま移せるとは限りません。データベースはHyperdrive経由になり、推奨ドライバの表ではPostgreSQL向けにpsycopgも挙がっています。公式のサンプルはFastAPIとasyncpg・aiomysqlが中心のため、ORM・マイグレーション・管理画面を含めた動作は検証してから判断してください。ファイルのアップロード先もR2などへ変える必要があります。
既存のTypeScriptのWorkerと組み合わせられますか?
組み合わせられます。PythonのWorkerもService Bindingsに対応しており、TypeScriptのWorkerから別のWorkerとして呼び出す構成が取れます。認証やルーティングは既存のTypeScript側に残し、Pythonのライブラリが必要な処理だけをPython Workerへ切り出す構成なら、移行の範囲を小さく保つことが可能です。実装例は公式のサンプル集にまとまっています。
関連記事
- サーバーレスWebAssemblyで何ができるか|Cloudflare・Fastly・Lambdaの上限とWASI 0.3の現在地:Python WorkersがWebAssembly上で動く前提と、各基盤の上限の違いを比べられます
- uvとは?Pythonの環境構築・パッケージ管理・バージョン管理の使い方を徹底解説:pywranglerが前提にするuvの基本操作を確認できます
- Uvicornとは?FastAPIを動かすPython製ASGIサーバーの基礎から本番デプロイまで:Workersでは不要になるASGIサーバーの役割を押さえられます
- Djangoとは?Python製Webフレームワークの特徴・MVT・始め方を入門解説:WSGIコネクタで載せる候補になるDjangoの基本を整理しています
- Cloudflare Workersのエッジ実行を比較|Lambda@Edge・Fastly・Akamaiとの違いとできること:エッジで処理を動かす選択肢を横並びで比較できます