TL;DR

Ngày 21/04/2026, Cloudflare ship một update nhỏ nhưng rất đáng chú ý cho Workflows: step.do() bây giờ chấp nhận ReadableStream<Uint8Array> làm giá trị trả về. Trước đây output mỗi step bị chặn ở 1 MiB, khiến việc chuyển một object R2 hay một file binary lớn giữa các step trở thành bài toán split/buffer thủ công. Từ nay chỉ cần return object.body. Cùng đợt, callback còn được bơm thêm context step.name, step.count, và config resolved.

What's new

Hai thay đổi chính trong bản 2026-04-21 của Cloudflare Workflows:

  • ReadableStream return type — step có thể trả stream trực tiếp thay vì phải tuần tự hoá thành JSON/Uint8Array fit trong 1 MiB.
  • Step context mở rộng — bên trong callback bạn đã có step.name (tên step), step.count (lần invocation thứ mấy, 1-indexed — cực hợp cho retry loop), và config đã resolved với timeout + retry (limit, delay, backoff).

Pattern điển hình — kéo một file lớn từ R2 rồi chuyền cho step sau:

const largePayload = await step.do("fetch-large-file", async () => {
  const object = await env.MY_BUCKET.get("large-file.bin");
  return object.body; // ReadableStream<Uint8Array>
});

Why it matters

Durable execution platform nào cũng phải trả lời câu hỏi: step A trả về một artifact lớn — làm sao đưa sang step B mà không mất state khi crash? Cách truyền thống: serialize toàn bộ vào storage, đọc lại ở step kế. Nhưng nếu output là file 50 MB, bạn phải hoặc (1) chặt nhỏ < 1 MiB rồi ghép lại, (2) upload R2 rồi pass reference, hoặc (3) buffer cả file vào RAM rồi hy vọng không OOM.

Stream return bỏ được bước trung gian: runtime tự ghi chunk-by-chunk vào instance state, step kế tiếp nhận lại stream mới có thể consume tuần tự. Đây là dấu hiệu Cloudflare đang đẩy Workflows thành primitive durable execution cho agentic workloads — thay vì chỉ là cron-job runner đẹp hơn.

Technical facts

Thông sốGiá trị
Max non-stream step result1 MiB (2^20 bytes) — cả Free và Paid
Kiểu stream hỗ trợReadableStream<Uint8Array> only (không BYOB)
Max chunk size khuyến nghị16 MB mỗi chunk
Per-instance state limit100 MB (Free) / 1 GB (Paid)
Max step / workflow1,024 (Free) / 10,000 mặc định, lên 25,000 (Paid)
Compute time / step10 ms (Free) / 30 s mặc định, lên 5 phút (Paid)
Event payload1 MiB trên cả hai plan

Ràng buộc khi trả stream: phải là stream mới được tạo trong callback, không locked, chưa được read, và chỉ dùng stream do step tự trả ra (không capture stream từ scope ngoài).

Comparison

So với đối thủ durable execution:

  • Temporal dùng activity result serialize qua payload converter, default payload cap 2 MB và có escape hatch lưu ngoài. Đòi hỏi tự config codec cho large payload.
  • Inngest cũng cap step output và khuyến nghị external storage cho blob lớn.
  • Trigger.dev v3 có io.backgroundFetch kiểu tương tự nhưng không phải native stream.

Ưu thế Cloudflare là tích hợp thẳng với ecosystem Workers + R2 + Durable Objects, không cần codec trung gian. Điểm yếu: output stream vẫn tính vào quota instance state, nên file quá lớn (GB trở lên) vẫn phải đẩy sang R2 và pass reference.

Use cases

  • R2 → step pipelines: fetch object 50 MB, truyền thẳng sang step transform/upload mà không OOM.
  • AI/agent workloads: pipe streaming output của LLM (token stream, audio, video frame) qua các step durable — crash giữa chừng vẫn resume được.
  • ETL jobs: CSV/Parquet hàng triệu dòng chảy từ ingest → transform → sink.
  • Binary processing: re-encode video, generate PDF, zip packaging khi artifact > 1 MiB.
  • Retry logic thông minh: dùng step.count để branch theo lần attempt (vd exponential jitter tự quản).

Limitations & pricing

Stream không phải viên đạn bạc:

  • Output stream vẫn tính vào instance state limit (100 MB Free / 1 GB Paid). Artifact GB trở lên bắt buộc qua R2 + reference.
  • Chỉ ReadableStream<Uint8Array>. Object stream, BYOB, stream đã locked hoặc đã consume đều bị reject.
  • Chunk quá 16 MB không đảm bảo chạy ổn — phải split ở upstream.
  • Không có pricing riêng cho feature này. Free plan vẫn giữ cap 10 ms compute, 1,024 step, 100 MB state.

What's next

Update này nằm trong chiến lược Workflows V2 — Cloudflare đã re-architect control plane với SousChef (distributed metadata manager) và Gatekeeper (concurrency leasing), nâng concurrent instances từ 4,500 lên 50,000, creation rate từ 100/s lên 300/s. Bước tiếp theo có khả năng là patterns native cho AI agents (long-running conversation state, tool-call orchestration), cộng với integration sâu hơn với Fluid Compute.

Nguồn: Cloudflare Changelog, Workflows Limits, Rules of Workflows, Workflows V2 blog.