Cloudflare Workflows に .subscribe() が追加 — 進捗確認のポーリングが不要になった
Cloudflare が 2026-09-15、Workflows のインスタンスイベントをポーリングなしでストリーム受信できる WorkflowInstance.subscribe() を追加した。Worker 内から呼ぶ方法と GET /subscribe の API 経由の両方に対応する。workflow レベルと step レベルの両方のイベント(attempts / sleeps / waits / rollbacks)を受け取れ、filter で種別を絞り、cursor で開始位置を指定できる。購読開始時にイベント履歴を最初から流し切り、そのあと新しいイベントを待つ。
ニュース原文を読む ↗要約
Cloudflare は 2026-09-15、Workflows のインスタンスイベントをポーリングなしでストリーム受信できる WorkflowInstance.subscribe() を追加しました。Worker の中から呼ぶ方法と、GET /subscribe の API エンドポイント経由の両方が用意されています。
Workflows は長時間実行される処理を扱う仕組みです。数分から数日にわたるジョブを、ステップ単位で中断・再開しながら進めます。ここで常に問題になるのが「今どこまで進んでいるか」を外から知る方法でした。
従来はポーリングでした。 一定間隔で状態を問い合わせ、変化があれば反映する。この方式には2つの無駄があります。 変化がないときも問い合わせが発生すること、そして変化が起きてから気づくまでに、ポーリング間隔ぶんの遅延が入ることです。間隔を短くすれば遅延は減りますが、無駄な問い合わせが増えます。このトレードオフが解消されます。
受け取れるのは workflow レベルと step レベルの両方のイベントで、公式は attempts(試行)、sleeps(待機)、waits、rollbacks を挙げています。filter パラメータで特定のイベント種別だけを購読できます。
購読の挙動に特徴があります。購読を開始すると、まずそのインスタンスのイベント履歴を最初から流し切り、そのあと実行の進行に合わせて新しいイベントを待ちます。 cursor パラメータを使えば、先頭からではなく特定のイベントから受信を始められます。
この「履歴を流し切ってからライブに切り替わる」設計は実務上重要です。 購読を始めたタイミングによって取りこぼしが起きません。接続が切れて再購読する場合も、cursor で続きから再開できます。
公式のコード例は次の形です。
const instance = await env.MY_WORKFLOW.get("report-123");
using subscription = await instance.subscribe();
while (true) {
const { value, done } = await subscription.next();
if (done) break;
console.log(value.type, value);
}
using 宣言を使っている点から、購読の後始末が明示的に扱われる設計であることが読み取れます。 購読を張りっぱなしにしてリソースを漏らす、という事故を言語機能の側で防ぐ形です。
想定ユースケースとして公式が挙げているのは、ユーザー向けダッシュボードでの Workflow 状態の更新、ステップ完了時の通知送信、特定イベントを契機にした後続処理のトリガーです。
何が変わったか
WorkflowInstance.subscribe()が追加。ポーリングなしでインスタンスイベントをストリーム受信できるGET /subscribeの API エンドポイント経由でも同じことができる- 受け取れるイベント: workflow レベルと step レベルの両方(attempts / sleeps / waits / rollbacks)
filterパラメータでイベント種別を絞れるcursorパラメータで受信開始位置を指定できる- 購読開始時にイベント履歴を最初から流し切り、その後ライブのイベントを待つ
- コード例は
using宣言を使い、購読の後始末を明示的に扱う形 - 想定用途: ダッシュボードの状態更新、ステップ完了時の通知、特定イベントを契機にした後続処理
業務インパクト(一般企業向け)
Workflows を使って長時間処理を実装している場合、これは実装を単純にする変更です。
まず、コストの話です。
ポーリング方式では、処理が進んでいない時間帯にもリクエストが発生し続けます。 数日かかるジョブを10秒間隔でポーリングすれば、それだけで数万回のリクエストになります。そのほとんどは「変化なし」という応答です。 購読方式にすれば、この分がなくなります。長時間ジョブを多数扱う構成ほど、差が大きくなります。
次に、実装の単純化です。
ポーリングを正しく実装するには、意外に考えることがあります。間隔をどうするか、指数バックオフを入れるか、前回の状態と比較して差分を検出する処理をどこに置くか、処理が終わったらポーリングをどう止めるか。 これらは本質的な業務ロジックではありません。購読方式では、これらの大半が不要になります。 イベントが来たら処理する、というだけです。
3点目、ユーザー体験への影響です。
社内向けであれ顧客向けであれ、「処理中」の画面ほど不満が出やすいものはありません。 ポーリング間隔が30秒なら、実際には5秒で終わった処理も最大30秒「処理中」と表示され続けます。購読方式なら、完了と同時に反映できます。 実装の手間が減ったうえで体験が良くなる、という珍しい種類の変更です。
導入を検討する際の注意点も挙げておきます。
接続の維持が前提になります。 ポーリングは各リクエストが独立しているため、途中で切れても次の問い合わせで復帰します。購読は接続が切れると止まります。 そのため、再接続と cursor を使った再開の処理は、自分で実装する必要があります。 公式が cursor を用意しているのは、まさにこのためです。「ポーリングより単純」なのは正常系だけで、異常系の設計は依然として必要です。
既存のポーリング実装を一斉に置き換える必要はありません。 動いているものは動いています。効果が大きいのは、(1) 実行時間が長いジョブ、(2) ポーリング間隔を短くしたいが増やせずにいた箇所、(3) これから新規に作る部分です。 この3つから順に適用するのが現実的です。
副業・個人活用視点
個人開発で Workflows を使っている場合、これは素直に嬉しい変更です。特に無料枠・低コストで運用している構成では、リクエスト数の削減が直接効きます。
個人開発で長時間処理を扱う典型は、バッチ的なデータ処理、外部 API の大量呼び出し、生成 AI を使った一括処理あたりです。 いずれも**「進捗を画面に出したい」という要求がほぼ必ず出ます。** そして、その進捗表示のためのポーリング実装が、想像より面倒だった経験は多くの人が持っているはずです。そこが簡単になります。
受託の立場では、これは提案の幅を広げる変更です。
「処理に時間がかかるので、完了したらメールで通知します」という設計は、顧客体験としては妥協です。 本当は画面で進捗が見えたほうがよい。しかし、進捗表示の実装コストが見合わないので、通知で済ませる。 こういう判断をした経験は、受託をしていれば必ずあります。
実装コストが下がると、この判断が変わります。 進捗表示を標準で入れられるなら、提案時の見え方が変わります。 同じ金額で、体験の質が1段上がったものを出せます。競合と並んだときに効くのは、たいていこういう部分です。
もう1つ、using 宣言に触れておく価値があります。
公式のコード例が using を使っているのは、購読のようなリソースを扱うときの作法が、言語機能として整ってきたことの表れです。個人開発では、リソースの後始末を忘れても、規模が小さいうちは表面化しません。 気づくのは、利用者が増えてからです。公式サンプルがこの形を採っているなら、素直に踏襲するのが安全です。 サンプルコードを写すときに using を普通の const に書き換えない、というだけの話ですが、ここを崩すと後で原因の分かりにくい問題になります。
注意点としては、Workflows 自体がまだ新しめの仕組みである点です。 学習コストはゼロではありません。単純なバッチ処理に Workflows を持ち込むと、過剰な構成になります。 「数日にわたる」「途中で失敗しても再開したい」「ステップごとに状態を残したい」という要件が揃って初めて選ぶ価値が出ます。今回の追加は便利ですが、Workflows を使う理由そのものにはなりません。