· cloudflare / aws / workers
Cách chuyển từ AWS sang Cloudflare 2026: Hướng dẫn đầy đủ
Workers cắt 50–80% chi phí Lambda, R2 zero egress. Hướng dẫn migrate đầy đủ: Lambda→Workers, S3→R2, RDS→D1, SQS→Queues — code trước/sau và khi nào không nên.
Bởi Ethan
2.735 từ · 14 phút đọc
Nếu bạn đang chạy một API JS/TypeScript trên Lambda + S3, phép tính chi phí khi chuyển sang Cloudflare giờ đây nghiêng về phía bạn. D1 đã GA vào tháng 4 năm 2024 và lấp đầy khoảng trống về database. Hyperdrive cho phép bạn giữ nguyên Postgres mà không cần chuyển đổi. Zero egress fees từ R2 giảm 60–80% chi phí lưu trữ cho các workload có egress cao. Với API nặng về I/O, Workers chỉ tính CPU time — không phải wall-clock — thường rẻ hơn Lambda 50–80% mỗi lần gọi.
Đây là playbook. Không phải bài so sánh hai nhà cung cấp — bài đó đã có rồi. Bài này nói về cách thực hiện migration.
Bài này dành cho ai
Các developer đang chạy Lambda, S3, CloudFront, API Gateway, hoặc DynamoDB với workload JavaScript hoặc TypeScript. Nếu bạn dùng Python, Java, Go, hay Ruby runtime — hoặc cần hơn 5 phút compute mỗi lần gọi — hãy đọc Khi nào KHÔNG nên migrate trước.
Bản đồ dịch vụ
Mỗi dịch vụ AWS bạn cần thay thế đều có một counterpart trực tiếp trên Cloudflare, và tất cả đều đã GA tính đến năm 2026:
| AWS | Cloudflare | Trạng thái |
|---|---|---|
| Lambda | Workers | GA |
| S3 | R2 | GA — $0.015/GB, zero egress |
| CloudFront + API Gateway | Workers routing / Pages | GA |
| RDS (PostgreSQL/MySQL) | D1 (SQLite) hoặc Hyperdrive (giữ RDS) | GA từ tháng 4/2024 |
| DynamoDB | Workers KV + Durable Objects | GA |
| SQS | Cloudflare Queues | GA |
| Kinesis | Cloudflare Pipelines | Open beta — chưa sẵn sàng cho production |
| Cognito | Cloudflare Access + Workers JWT | GA |
| SageMaker / Bedrock | Workers AI | GA, 50+ models |
Một lưu ý: Pipelines (bản thay thế Kinesis) vẫn đang trong open beta tính đến tháng 5 năm 2026. Chưa nên chuyển event stream production qua đây.
Nếu bạn đang cân nhắc giữa Lambda và Workers trước khi migrate, xem Cloudflare Workers vs AWS Lambda: So Sánh Serverless 2026 để hiểu rõ giới hạn và pricing của từng bên.
Đăng ký Cloudflare Workers để bắt đầu — R2, D1, Queues, và Workers KV đều được bật từ cùng một dashboard.
Compute: Lambda → Workers
Workers là một serverless runtime JavaScript/TypeScript/WebAssembly nền tảng V8, triển khai trên 330+ thành phố tại 100+ quốc gia. Không có cold starts — V8 isolates, không phải container.
Việc chuyển đổi code chủ yếu là thay đổi cú pháp, không phải logic:
Trước (Lambda/Node.js):
exports.handler = async (event, context) => {
const body = JSON.parse(event.body || '{}');
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'Hello', input: body })
};
};
Sau (Cloudflare Worker — ESM):
export default {
async fetch(request, env, ctx) {
const body = await request.json();
return Response.json({ message: 'Hello', input: body });
}
};
Bốn điều đã thay đổi:
- Workers dùng Fetch API (
Request/Response) — cùng chuẩn với browser, không phải Lambda event envelope. - Workers là ESM modules, không phải CommonJS.
envthay thếprocess.env. Các binding (R2, D1, KV) nằm trực tiếp trênenv— không cần khởi tạo SDK client.- Không còn phải xử lý
context.callbackWaitsForEmptyEventLoop.
Deploy chỉ với một lệnh: wrangler deploy. So sánh với SAM, CDK, hay Terraform trên AWS.
wrangler.toml đầy đủ
Cấu hình này kết nối tất cả các primitive bạn sẽ dùng trong một migration điển hình:
name = "my-app"
main = "src/index.ts"
compatibility_date = "2026-05-23"
[[r2_buckets]]
binding = "ASSETS"
bucket_name = "my-app-assets"
[[d1_databases]]
binding = "DB"
database_name = "my-app-db"
database_id = "your-database-id-here"
[[kv_namespaces]]
binding = "CACHE"
id = "your-kv-namespace-id"
[[queues.producers]]
binding = "JOB_QUEUE"
queue = "my-app-jobs"
[[queues.consumers]]
queue = "my-app-jobs"
max_batch_size = 10
max_batch_timeout = 30
max_retries = 3
dead_letter_queue = "my-app-jobs-dlq"
Giá cả: Lambda vs Workers
| Chiều | AWS Lambda | Cloudflare Workers |
|---|---|---|
| Requests (trả tiền) | $0.20/triệu | $0.30/triệu |
| Tính phí compute | Duration × memory (wall-clock) | Chỉ CPU time |
| Data transfer out | $0.09/GB | $0 |
| Tối thiểu hằng tháng | $0 pay-as-you-go | $5/tháng (Workers Paid) |
Giá request của Workers trông cao hơn, nhưng cách tính phí compute đảo ngược tình thế. Nếu Lambda function chạy 200ms nhưng chỉ dùng 15ms CPU (phần còn lại là chờ I/O), Lambda vẫn tính bạn 200ms. Workers chỉ tính 15ms. Đó là nơi khoản tiết kiệm 50–80% đến từ, với các API nặng I/O.
Xem giá hiện tại tại Cloudflare Workers Pricing và AWS Lambda Pricing.
Giới hạn của Workers cần biết trước
- Runtime: Chỉ JS/TS/WASM. Không có Python, Java, Go, hay Ruby.
- Memory: Tối đa 128MB. Lambda scale lên đến 10GB.
- CPU: Giới hạn mặc định 30 giây, tối đa 5 phút trên Paid plan.
- Không có persistent filesystem: Không có
/tmp. Mọi thứ đưa vào R2, KV, hoặc D1. - Không có Docker images: Không thể lift-and-shift một containerized Lambda.
Nguồn: Workers Limits
Lưu trữ: S3 → R2
R2 là object storage tương thích S3 với zero egress fees. Hầu hết các S3 SDK đều hoạt động với cấu hình lại tối thiểu — bạn chỉ thay đổi endpoint, không phải API.
Cấu hình lại S3 client
// Trước: AWS S3
import { S3Client } from '@aws-sdk/client-s3';
const s3 = new S3Client({ region: 'us-east-1' });
// Sau: R2 (cùng SDK, endpoint khác)
const r2 = new S3Client({
region: 'auto',
endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
credentials: {
accessKeyId: R2_ACCESS_KEY_ID,
secretAccessKey: R2_SECRET_ACCESS_KEY,
}
});
R2 hỗ trợ tất cả các operation bạn thường dùng: PutObject, GetObject, HeadObject, DeleteObject, ListObjectsV2, CopyObject, và multipart uploads. Những gì nó không hỗ trợ: ACLs, bucket policies, AWS KMS server-side encryption, và object tagging.
Migration dần dần với Sippy
Bạn không cần copy tất cả cùng một lúc. Tính năng Sippy của Cloudflare migrate object theo yêu cầu: khi có request đến R2 cho một object chưa tồn tại, R2 sẽ lấy từ S3 và lưu lại. Sau khi traffic của bạn chuyển sang R2, các object sẽ migrate dần khi được truy cập. Không cần copy job lớn, không downtime.
Giá cả: S3 vs R2
| Chiều | AWS S3 (Standard) | Cloudflare R2 (Standard) |
|---|---|---|
| Lưu trữ | $0.023/GB-tháng | $0.015/GB-tháng |
| Egress | $0.09/GB (sau 100GB miễn phí) | $0 luôn luôn |
| Free tier | 5GB, 20K GETs, 2K PUTs | 10GB, 10M GETs, 1M PUTs |
Với 100TB lưu trữ + 10TB egress hằng tháng:
- S3: ~$1,500 lưu trữ + ~$921 egress = ~$2,421/tháng
- R2: ~$1,500 lưu trữ + $0 egress = ~$1,500/tháng
Ở quy mô 1PB với egress cao, con số này tăng theo cấp số nhân. Xem giá hiện tại tại R2 Pricing và R2 vs S3 Calculator.
CDN và routing: CloudFront + API Gateway → Workers
Workers đứng trước traffic của bạn trên toàn cầu — không cần cấu hình distribution riêng. Một Worker duy nhất xử lý routing, caching, A/B testing, auth, và response transformation. Bạn không trả thêm cho một CDN layer riêng biệt.
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname.startsWith('/static/')) {
return env.ASSETS.fetch(request);
}
if (url.pathname.startsWith('/api/')) {
return handleApi(request, env);
}
return env.ASSETS.get('index.html').then(obj =>
new Response(obj.body, { headers: { 'Content-Type': 'text/html' } })
);
}
};
Loại bỏ API Gateway
API Gateway tính $1.00–$3.50/triệu request trên Lambda costs. Với Workers, API routing được tích hợp vào Worker — không có gateway charge riêng.
| Dịch vụ | Chi phí |
|---|---|
| AWS API Gateway (HTTP) | $1.00/triệu requests |
| AWS API Gateway (REST) | $3.50/triệu requests |
| Cloudflare Workers routing | Bao gồm trong Workers request cost |
Nguồn: Amazon API Gateway Pricing
Security cũng là một khoản bạn không còn phải lo. Cloudflare bao gồm DDoS protection và WAF không giới hạn trên tất cả các plan. AWS Shield Advanced tốn $3,000/tháng cộng usage fees.
Database: RDS và DynamoDB → D1, KV, và Hyperdrive
Bạn có hai chiến lược. Chọn dựa trên độ phức tạp của schema.
Chiến lược A: Migrate sang D1 (app nhỏ đến trung bình)
D1 là managed serverless SQLite database của Cloudflare. GA từ tháng 4 năm 2024, với global read replication đang trong beta từ tháng 4 năm 2025 mà không tốn thêm phí.
# Tạo database
wrangler d1 create my-app-db
# Áp dụng schema migration
wrangler d1 execute my-app-db --file ./schema.sql
// Query từ Worker
const result = await env.DB.prepare(
'SELECT * FROM users WHERE id = ?'
).bind(userId).first();
Những điểm cần chú ý khi migrate PostgreSQL → D1:
INTEGER PRIMARY KEYthay vìSERIAL/BIGSERIAL- Không có kiểu UUID native — lưu dạng TEXT
- Không có
ARRAYhayJSONB— dùng JSON functions - Không có stored procedures hay PL/pgSQL
- ALTER TABLE bị giới hạn (không có DROP COLUMN trong SQLite < 3.35)
D1 xử lý đến 10GB mỗi database. Với dataset lớn hơn, dùng D1 làm primary store với R2 cho blob data.
Giá (Paid plan): bao gồm 25 tỷ rows read/tháng + 50 triệu rows written/tháng. Nguồn: D1 Overview
Chiến lược B: Giữ RDS, dùng Hyperdrive (schema phức tạp)
Nếu schema của bạn dùng PostgreSQL extensions, stored procedures, row-level security, hay các join phức tạp — đừng migrate database. Dùng Hyperdrive thay thế. Nó cho phép Workers kết nối đến RDS instance hiện có với connection pooling và tự động cache read query tại edge. Không cần thay đổi gì ở database layer.
# wrangler.toml
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "your-hyperdrive-id"
import { Client } from 'pg';
export default {
async fetch(request, env) {
const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
await client.connect();
const result = await client.query('SELECT * FROM users WHERE id = $1', [id]);
await client.end();
return Response.json(result.rows[0]);
}
};
Hyperdrive xử lý connection pool management, cache read query tại edge, và hoạt động với Drizzle, Prisma, Knex, và TypeORM. Giá: miễn phí cho Workers Paid plan. Nguồn: Hyperdrive Overview
DynamoDB đơn giản KV → Workers KV
Với các DynamoDB table dùng như key-value store (tra cứu theo primary key, không có complex query):
// Trước: DynamoDB GetItem
const item = await dynamoDB.getItem({
TableName: 'sessions',
Key: { sessionId: { S: sessionId } }
}).promise();
// Sau: Workers KV
const session = await env.SESSIONS.get(sessionId, { type: 'json' });
Workers KV: bao gồm 10M reads/tháng + 1M writes/tháng trong Paid plan. Globally replicated, eventually consistent. Để có strong consistency, dùng Durable Objects thay thế.
Queues: SQS → Cloudflare Queues
Cloudflare Queues cung cấp guaranteed at-least-once delivery, batching, retries, delays, và dead-letter queues — tích hợp trực tiếp vào Workers.
Producer:
export default {
async fetch(request, env) {
const job = await request.json();
await env.JOB_QUEUE.send(job);
return new Response('Queued', { status: 202 });
}
};
Consumer:
export default {
async queue(batch, env) {
for (const message of batch.messages) {
await processJob(message.body, env);
message.ack();
}
}
};
Cấu hình queue trong wrangler.toml:
[[queues.producers]]
binding = "JOB_QUEUE"
queue = "my-app-jobs"
[[queues.consumers]]
queue = "my-app-jobs"
max_batch_size = 10
max_batch_timeout = 30
max_retries = 3
dead_letter_queue = "my-app-jobs-dlq"
Giá cả:
- SQS Standard: $0.40/triệu messages
- SQS FIFO: $0.50/triệu messages
- Cloudflare Queues: bao gồm trong Workers Paid ($5/tháng cơ bản)
Nguồn: Cloudflare Queues
Auth: Cognito → Cloudflare Access hoặc Workers JWT
Hai lựa chọn tùy theo trường hợp sử dụng.
Lựa chọn A: Cloudflare Access (công cụ nội bộ và B2B)
Cloudflare Access thay thế Cognito + API Gateway authorizers để bảo vệ các app nội bộ và admin interface. Cấu hình trong dashboard — không cần thay đổi code. Nó tích hợp với identity provider hiện có: Google, GitHub, Okta, SAML, hoặc OIDC. Bạn có thể giữ Cognito làm IdP và dùng Access làm policy enforcement layer:
# Cloudflare dashboard → Zero Trust → Access → Applications
# Add application → Self-hosted
# Set Access policy: "allow @company.com Google accounts to reach /admin"
Nguồn: Tích hợp Cognito OIDC với Cloudflare Access
Lựa chọn B: Workers JWT verification (API public-facing)
Với các app cần user pools của Cognito (đăng ký, đăng nhập, reset mật khẩu), lựa chọn là dùng một third-party auth service (Auth0, Clerk, Supabase Auth) hoặc xác thực JWT trực tiếp trong Worker:
import { jwtVerify, createRemoteJWKSet } from 'jose';
const JWKS = createRemoteJWKSet(
new URL('https://your-auth-provider.com/.well-known/jwks.json')
);
export default {
async fetch(request, env) {
const token = request.headers.get('Authorization')?.replace('Bearer ', '');
try {
const { payload } = await jwtVerify(token, JWKS);
return handleRequest(request, env, payload);
} catch {
return new Response('Unauthorized', { status: 401 });
}
}
};
Khi nào KHÔNG nên migrate {#when-not-to-migrate}
Phần này quan trọng. Cloudflare không phải câu trả lời đúng cho mọi team.
Bạn đang dùng runtime không phải JS. Workload ML bằng Python, microservices Java, service Go — Lambda hỗ trợ tất cả. Workers chỉ chạy JavaScript, TypeScript, và WebAssembly. Đây là rào cản số 1 khiến hầu hết các team ở lại AWS.
Bạn cần compute chạy lâu. Video encoding, inference model lớn, ETL jobs — Lambda hỗ trợ đến 15 phút wall time. Workers tối đa 5 phút CPU trên Paid plan (30 giây theo giới hạn mặc định). Nếu Lambda function của bạn thường xuyên chạy đến 10–15 phút, đừng migrate compute.
Bạn phụ thuộc sâu vào hệ sinh thái data của AWS. Step Functions, Glue, Athena, EMR, Redshift — Cloudflare không có tương đương. Hyperdrive kết nối RDS của bạn, nhưng data platform xung quanh còn mỏng.
Schema PostgreSQL phức tạp. D1 là SQLite. PostgreSQL extensions (PostGIS, pg_vector, tsvector full-text search), row-level security, và stored procedures phức tạp không thể chuyển đổi gọn gàng. Dùng chiến lược Hyperdrive bridge thay vì migrate toàn bộ sang D1.
Bạn cần data residency tại các AWS region cụ thể. Cloudflare vận hành trên toàn cầu với ít chứng chỉ tuân thủ hơn cho các ngành có quy định yêu cầu data residency theo từng vùng lãnh thổ.
Batch job cần nhiều memory. Workers giới hạn 128MB. Lambda scale lên đến 10GB.
Thay thế Kinesis cho production. Cloudflare Pipelines vẫn trong open beta tính đến tháng 5 năm 2026. Với event streaming production, dùng Workers + Queues + R2 với custom batching, hoặc Hyperdrive để kết nối Kafka.
So sánh chi phí và kết luận
Những team tiết kiệm nhiều nhất từ migration này đều có chung một đặc điểm: egress lớn từ S3, API Gateway + Lambda trên mỗi request, và TypeScript code nặng về I/O. Baselime — migrate trong 3 tháng, team 3 kỹ sư, theo mô hình strangler-fig — giảm chi phí cloud từ $708K xuống còn $118K/năm (giảm 83%). Để xem breakdown hóa đơn thực tế từ 15M đến 1 tỷ requests, đọc Cloudflare vs AWS: phân tích hóa đơn thực tế khi scale.
Các con số ở quy mô lớn (cập nhật đến 2026-05):
| Tình huống | AWS hằng tháng (ước tính) | Cloudflare hằng tháng (ước tính) |
|---|---|---|
| 100M API requests | ~$220 (Lambda + APIGW) | ~$45 (Workers) |
| 1TB lưu trữ + 10TB egress | ~$2,421 (S3) | ~$1,500 (R2) |
| 100K SQS messages/ngày | ~$1.20 | $0 (bao gồm) |
| DDoS + WAF | $3,000+ (Shield Advanced) | $0 (bao gồm) |
Giá thay đổi theo thời gian. Tham khảo các máy tính giá:
- Cloudflare Workers Pricing
- R2 Pricing | R2 vs S3 Calculator
- AWS Lambda Pricing
- AWS S3 Pricing
- Amazon API Gateway Pricing
Migration mang lại hiệu quả nhanh nhất khi chi phí của bạn tập trung vào egress và API Gateway. Nếu bạn chạy Python hay Go, hoặc có schema RDS phức tạp không thể đơn giản hóa, Cloudflare phù hợp hơn như một migration một phần (Workers cho edge logic, Hyperdrive cho database) thay vì chuyển đổi hoàn toàn. Hãy tính toán trên hóa đơn thực tế của bạn trước khi quyết định.
Đăng ký Cloudflare Workers và R2 để bắt đầu — bạn có thể chạy free tier song song với AWS cho đến khi sẵn sàng chuyển đổi hoàn toàn.