Vì sao Worker thay vì một server
Cloudflare Worker là isolate, không phải process — khởi động theo request, xử lý xong rồi không giữ RAM hay connection giữa các lần gọi. Không server cần hâm nóng, không fleet cần scale, không region cần chọn; cùng một script chạy ở mọi edge Cloudflare. Với gateway mà việc chỉ là «nhận request, chọn upstream, stream response về», mô hình theo request rất hợp — nhưng mọi quyết định kiến trúc phải tôn trọng giới hạn isolate mà server thường không có.
Hai giới hạn định hình hầu hết phần còn lại: trần 128MB RAM mỗi isolate, và trần script nén 3MiB mỗi Worker.
Stream, đừng bao giờ buffer
Trần 128MB biến một pattern server phổ biến thành nguy hiểm: đọc hết response upstream vào RAM rồi mới forward. Completion LLM có thể dài vô hạn, và await response.text() trên stream không biên không có trần riêng — nó phình đến khi isolate hết bộ nhớ.
| Anti-pattern | Why it breaks | Correct pattern |
|---|---|---|
await response.text() on unbounded upstream data | Memory exhaustion against the 128MB isolate limit | Stream: return new Response(readableStream, { headers }) |
| Module-level mutable state for request data | Cross-request leakage between isolates handling different users | Per-request state on c.set(...) or closures |
| Floating promises for background work | Dropped results, swallowed errors after the response returns | c.executionCtx.waitUntil(promise) |
Thực tế, chat completions, Anthropic messages và Responses API đều trả Response gốc bọc SSE của upstream, dịch dialect từng chunk thay vì gom rồi phát lại:
export default (async (c) => {
const upstream = await fetch(upstreamUrl, { method: "POST", body, headers })
// Never buffer: pipe the upstream stream straight through,
// translating SSE dialect chunk-by-chunk as it passes.
return new Response(upstream.body.pipeThrough(dialectTranslator), {
status: upstream.status,
headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache" },
})
}) satisfies HonoHandlerTrần 3MiB buộc tách nhiều Worker
Một Worker đơn vượt trần script nén 3MiB của Cloudflare khi engine routing, catalog, Durable Objects, MCP, OAuth và cả bề mặt Hono API nằm chung một script. Cách xử lý là hub-and-spoke: một web Worker giữ route toàn zone, rồi forward sang spoke qua service binding, hoặc tự serve trang.
| Worker | Host | Owns |
|---|---|---|
| anyrouter (web hub) | anyrouter.dev (apex) | SSR landing pages; routes and forwards everything else |
| anyrouter-api | service binding only | Hono app, executor, catalog, Durable Objects |
| anyrouter-dashboard | dash.anyrouter.dev | Dashboard app |
| anyrouter-admin | admin.anyrouter.dev | Admin app |
| anyrouter-mcp | service binding only | MCP server (JSON-RPC + OAuth) |
| anyrouter-flow | cron + service binding | Workflows and scheduled jobs |
Mỗi spoke proxy /api/* cùng origin sang anyrouter-api qua service binding, nên trình duyệt không bao giờ cross-origin — không cần CORS, cũng không mở thêm bề mặt public cho từng Worker.
Mọi upstream đi qua AI Gateway
Dispatch tới nhà cung cấp mô hình thật sự đi đúng một trong ba hình transport, tất cả đổ vào Cloudflare AI Gateway chứ không gọi API nhà cung cấp trực tiếp:
| Transport | Reaches | How |
|---|---|---|
| Workers AI binding | First-party and partner-hosted Workers AI catalog models | c.env.AI.run(model, body, { gateway: { id }, returnRawResponse: true }) |
| Unified AI Gateway REST | CF unified-billing catalog, third-party models | One API token, cf-aig-gateway-id header, usage bills via Unified Billing |
| Per-provider AI Gateway REST | BYOK and direct providers (OpenAI, Anthropic, xAI, Groq, DeepInfra, ...) | cf-aig-authorization header plus the provider's own key in Authorization |
Tách này vô hình với người dùng cuối — mọi backend dùng cùng huy hiệu «Cloudflare AI Gateway» dù transport nào phục vụ. Quy tắc phía sau chặt hơn nghe: mọi upstream phải đi gateway.ai.cloudflare.com, đúng một ngoại lệ đã ghi: backend first-party không có HTTP origin để proxy (nó tới thiết bị của user qua WebSocket outbound).
Primitive bảo mật mà edge cho sẵn
Chạy trên Workers cũng nghĩa là primitive crypto của nền tảng là mặc định, không phải dependency thêm:
crypto.getRandomValues()orcrypto.randomUUID()— neverMath.random()for tokens or idscrypto.subtlefor all cryptographic operations, including per-row encryption at restcrypto.subtle.timingSafeEqualfor secret comparison, so key checks aren't timing-attackable- Secrets live in
wrangler secret put, never hardcoded in source or committed config
Xử lý lỗi tường minh cũng quan trọng hơn framework có trang exception toàn cục — cố ý tránh passThroughOnException(), vì nó giấu bug thật sau fallback im lặng thay vì đưa lên error handler của Hono để log và sửa.
Edge đánh đổi gì
Không thứ nào miễn phí. Mọi giới hạn trên là ràng buộc kiến trúc phải vòng, không phải đã xóa — trần 3MiB nghĩa là tính năng mới phải nghĩ thuộc Worker nào, và quy tắc chỉ-stream nghĩa là không có lối tắt post-process cả response trước khi tới client. Đổi lại là script chạy giống nhau ở mọi edge, không có fleet server phía sau.

Xem vòng đời request, catalog và routing live trong tài khoản của bạn.
Mở dashboardGửi request đầu trong hai phút
Bắt đầu miễn phí với key của bạn, hoặc nạp rồi trả theo token. Go: $4 credit/tháng — $2/tháng, hoặc miễn phí khi góp một provider key.
Bắt đầu miễn phí