Một workflow chạy êm cả tháng, request không tăng mấy, CPU cũng chẳng đáng bao nhiêu. Tới ngày 10/8/2026, nếu vẫn chỉ nhìn hai con số đó thì mình có thể bỏ quên đúng hai phần mới đi vào chi phí Cloudflare Workflows: step và state được lưu.
Mình không có hóa đơn Workflows thật để khoe. Trong bài này mình mở lại bảng giá ngày 10/8, dựng một script local với bốn input và kiểm tra ba mốc dưới, đúng, trên quota. Kết quả hữu ích nhất không phải một con số “dùng Cloudflare tốn bao nhiêu”, mà là cách tách đúng bốn đồng hồ trước khi nhân.
Mục lục [Hiển thị]
Ngày 10/8 thay đổi điều gì trên hóa đơn?
Changelog Workflows ngày 7/7 nói Cloudflare không thu step và storage trước 10/8. Đến lúc mình kiểm tra ngày 10/8, trang pricing chính thức ghi thẳng billing hai phần này áp dụng từ ngày 10/8/2026.
Trên Workers Paid, mỗi tháng có 500.000 step và 1 GB-month storage trong quota. Phần vượt là 0,80 USD cho mỗi 100.000 step và 0,20 USD cho mỗi GB-month. Request và CPU không phải giá mới: chúng dùng chung Workers Standard, lần lượt có 10 triệu request và 30 triệu CPU-ms trong tháng trước phần overage.
Workers Free có 3.000 step mỗi ngày và 1 GB storage, nhưng Cloudflare nói developer Free không bị tính overage step/storage. Chỗ này đừng hiểu thành “vượt bao nhiêu cũng chạy”: tài liệu xác nhận một instance cố ghi state khi đã chạm giới hạn storage Free sẽ lỗi. Với step, trang pricing chỉ khẳng định không thu tiền vượt quota; mình không suy diễn thêm cơ chế chặn khi docs không nói rõ.
Bốn đơn vị dễ bị cộng nhầm
Mình lấy một instance làm ví dụ: nó được kích hoạt một lần, chạy 20 step, dùng 200 ms CPU và góp vào 1,4 GB-month state của cả account. Bốn số này thuộc bốn quota riêng; không có phép đổi “20 step bằng 20 request”. Subrequest do workflow gọi ra cũng không phát sinh thêm request cost của Workflows, dù vẫn chịu giới hạn kỹ thuật riêng.

CPU chỉ đo thời gian xử lý chủ động. Workflow chờ API, ngủ bằng step.sleep() hoặc đứng đợi event không ăn CPU cho phần thời gian chờ. Đây là chỗ wall-clock một ngày không có nghĩa là CPU một ngày. Nếu các bạn từng debug công cụ Cloudflare, bài mình thử pvcli cũng có cùng bài học: phải gọi đúng tên metric trước khi kết luận.
Một step thực sự được đếm thế nào?
Pricing định nghĩa step là đơn vị công việc được workflow thực thi. step.do(), step.sleep() và step.waitForEvent() đều là step tính phí. Tuy vậy, retry của một step và rollback handler không nằm trong step count. Sleep còn có một nét dễ nhầm: nó tính là step cho billing, nhưng không tính vào giới hạn tối đa step của một instance.
Mình sẽ không gộp mười API call vào một step.do() chỉ để bảng tính đẹp. Boundary step quyết định nơi retry, cache kết quả và phục hồi. Tiết kiệm vài chục cent mà biến một đoạn idempotent thành một cục khó khôi phục thì hơi ngược đời.
Mình tính ba workload từ 5 đến 100 step
Script local nhận bốn input: số lượt chạy, step mỗi lượt, CPU-ms mỗi lượt và GB-month. Công thức step rất ngắn: max(0, tổng step - 500.000) / 100.000 × 0,80 USD. Mình kiểm tra thêm 499.999, 500.000 và 500.001 step để tránh lỗi biên.
| Ca | Lượt/tháng | Step/lượt | Tổng step | Phí step vượt | Storage | Phí storage vượt |
|---|---|---|---|---|---|---|
| Nhỏ | 80.000 | 5 | 400.000 | 0 USD | 0,4 GB-mo | 0 USD |
| Vừa | 30.000 | 20 | 600.000 | 0,80 USD | 1,4 GB-mo | 0,08 USD |
| Lớn | 8.000 | 100 | 800.000 | 2,40 USD | 4 GB-mo | 0,60 USD |

Quota 500.000 tương đương tối đa 100.000 lượt nếu mỗi lượt 5 step, 25.000 lượt nếu 20 step và 5.000 lượt nếu 100 step. Ba workload của mình cố tình dùng số lượt khác để cho thấy ít invocation vẫn có thể ăn nhiều step. Trong cả ba ca, request và CPU đều còn dưới quota riêng, nên tổng variable cost lần lượt là 0; 0,88; và 3 USD. Con số đó chưa gồm phí nền Workers Paid hay sản phẩm khác.
Đọc usage bằng dashboard và GraphQL
Nếu có account thật, đường ngắn nhất là Dashboard → Workflows → chọn workflow → chọn khoảng thời gian. Cloudflare nói chart ở đây dùng cùng GraphQL Analytics API và dữ liệu metric được giữ 31 ngày. Mình không đăng nhập account của người khác, không tạo workload trả phí và không chụp dashboard giả.
Truy vấn một instance để nhìn stepCount
Với một instance cụ thể, tài liệu đưa dataset raw workflowsAdaptive. Query dưới đây trả timeline có eventType, stepCount và wallTime. Account ID, instance ID và token phải truyền qua biến/header riêng, không commit vào source.
query WorkflowUsage(
$accountTag: string!
$datetimeStart: Time
$datetimeEnd: Time
$instanceId: string
) {
viewer {
accounts(filter: { accountTag: $accountTag }) {
workflowsAdaptive(
limit: 100
filter: {
datetime_geq: $datetimeStart
datetime_leq: $datetimeEnd
instanceId: $instanceId
}
orderBy: [datetime_ASC]
) {
datetime
eventType
workflowName
stepCount
wallTime
}
}
}
}
Tài liệu metrics cũng có workflowsAdaptiveGroups để nhóm theo workflowName, eventType và thời gian. Mình sẽ dùng groups để theo dõi số lần WORKFLOW_START, còn khi điều tra một run thì quay về raw timeline. Đếm số step.do() trong code bằng mắt không đủ vì nhánh điều kiện, loop, sleep và event làm đường chạy khác nhau.
Retention khiến storage tăng ở chỗ nào?
GB-month không phải kích thước payload ở đúng một thời điểm. Cloudflare lấy trung bình peak storage mỗi ngày trong kỳ 30 ngày, cộng trên cả instance running, errored, sleeping và completed. Paid mặc định giữ state 30 ngày, Free là 3 ngày. Vì vậy một workflow hoàn thành nhanh vẫn có thể để state nằm lại gần trọn tháng.
Workers API cho phép đặt successRetention và errorRetention khi tạo instance:
await env.REPORT.create({
id: reportId,
params: { objectKey },
retention: {
successRetention: "1 day",
errorRetention: "7 days",
},
});
Mình sẽ rút success retention cho report có thể tạo lại, nhưng giữ error lâu hơn để debug. Với payload lớn, trang limits khuyên lưu artifact dài hạn ở R2 rồi trả về một reference. Cách này giảm state Workflows; nó không tự giảm số step, request hay CPU.
Tối ưu step mà không làm workflow khó phục hồi
Trước khi gộp step, mình hỏi ba câu: thao tác có idempotent không, nếu retry thì phạm vi nào an toàn, và khi lỗi mình cần nhìn kết quả trung gian nào? Hai call độc lập có thể chạy song song nhưng vẫn giữ hai step. Hai phép biến đổi thuần túy, nhỏ và luôn đi cùng nhau có thể nằm chung nếu việc phục hồi không bị tệ hơn.
Đừng tối ưu dựa trên một ngày yên ắng. Log số run, phân phối step/run thay vì chỉ lấy trung bình, GB-month và tỷ lệ retry. Sau đó đặt cảnh báo ở 70–80% quota. Script tính cost cũng nên có test biên giống cách mình đặt quality gate cho coverage Node.js 26.7; một phép nhân sai trong automation đủ làm dashboard rất tự tin mà vẫn sai.
Checklist trước kỳ bill đầu tiên
- Xác nhận plan, pricing và ngày hiệu lực ngay trong docs.
- Lấy invocation và stepCount từ Dashboard/GraphQL, không đếm source bằng mắt.
- Tách request, CPU, storage và step thành bốn quota.
- So cả trung bình lẫn percentile của step/run.
- Rút retention khi lịch sử thành công không còn giá trị.
- Đưa artifact lớn sang R2 và chỉ persist reference khi phù hợp.
- Giữ boundary retry/idempotency trước khi nghĩ tới việc gộp step.
- Review thay đổi workflow như một thay đổi vận hành; checklist GitHub Actions an toàn là một mẫu khá ổn.
Chốt lại, thay đổi ngày 10/8 không làm Workflows bỗng khó dùng. Nó chỉ buộc mình thôi gọi mọi thứ là request. Với workload nhỏ, quota 500.000 step và 1 GB-month có thể vẫn dư; với workflow nhiều nhánh hoặc giữ state lâu, hai dòng mới đáng theo dõi ngay từ hôm nay.
Nguồn: Cloudflare Workflows Changelog (7/7/2026), Pricing (cập nhật 21/7/2026), Limits (cập nhật 15/6/2026), Metrics and analytics (cập nhật 5/6/2026), Workers API; kiểm tra ngày 10/8/2026. Các phép tính là mô phỏng local từ bảng giá chính thức, không phải dữ liệu billing của một account thật.