Skip to content

Serverless & Edge Computing — Kiến trúc không máy chủ

Một API endpoint đơn giản xử lý image resize. Traffic: 0 requests lúc 3 giờ sáng, 10.000 requests/phút lúc flash sale. Với kiến trúc truyền thống, bạn phải duy trì server 24/7 — trả tiền cho 23 giờ idle để phục vụ 1 giờ peak. Với serverless, bạn trả chính xác cho 10.000 invocations trong giờ peak, và $0 khi không có traffic. Đó là promise hấp dẫn nhất của serverless — pay-per-use ở mức granular nhất.

Nhưng promise đó đi kèm trade-offs mà nhiều kỹ sư bỏ qua: cold start thêm 200ms-5s latency cho request đầu tiên, vendor lock-in khiến migration tốn hàng tháng engineering effort, và chi phí thực tế ở high-traffic workloads có thể đắt hơn dedicated servers. Hơn nữa, edge computing đang mở ra paradigm mới — chạy code ngay tại CDN edge node, cách user chỉ 10-50ms thay vì 200-500ms đến origin server.

Bài này phân tích serverless và edge computing từ góc nhìn production engineering — không phải marketing slides của cloud providers.

Bức tranh tư duy

Hãy so sánh ba mô hình kinh doanh ẩm thực:

Dedicated Server giống như bạn thuê một nhà hàng cố định. Trả tiền thuê mặt bằng hàng tháng, dù ngày vắng khách hay đông khách. Bạn kiểm soát mọi thứ: bếp, bàn ghế, nhân viên. Nhưng ngày vắng khách vẫn phải trả đủ tiền thuê.

Serverless (FaaS) giống như bạn đăng ký dịch vụ bếp chia sẻ (cloud kitchen). Không cần thuê mặt bằng. Khi có đơn hàng, bếp được cấp cho bạn, nấu xong trả lại. Trả tiền theo số món nấu. Nhưng: mỗi lần bắt đầu nấu cần 5 phút "khởi động" (cold start), và bạn không chọn được bếp nào (vendor lock-in).

Edge Computing giống như bạn đặt xe đẩy bán đồ ăn ở mọi ngã tư trong thành phố. Khách hàng không cần đến nhà hàng trung tâm — có xe đẩy ngay cạnh. Nhưng: xe đẩy nhỏ, chỉ phục vụ được menu đơn giản (compute constraints ở edge), và đồng bộ menu giữa 50 xe đẩy là thách thức.

Giới hạn phép so sánh: Cloud kitchen có thể từ chối đơn hàng quá phức tạp — serverless cũng vậy (timeout limits, memory limits). Xe đẩy không thể nấu phở — edge functions không thể chạy ML inference nặng.

Cốt lõi kỹ thuật

FaaS — Function as a Service

FaaS cho phép deploy individual functions mà không quản lý server. Cloud provider xử lý provisioning, scaling, patching. Mỗi function invocation là một isolated execution environment.

Execution Model:

  1. Request đến → Platform kiểm tra có warm instance không
  2. Nếu có → route request đến warm instance (hot start: 1-5ms overhead)
  3. Nếu không → tạo instance mới: download code, init runtime, execute (cold start: 100ms-5s)
  4. Function xử lý request, trả response
  5. Instance giữ "warm" một khoảng thời gian (thường 5-15 phút)
  6. Nếu không có request → instance bị recycle

So sánh các FaaS platforms:

PlatformMax TimeoutMemoryCold Start (ước lượng)Language Support
AWS Lambda15 phút10GB100ms-3sNode, Python, Java, Go, .NET, Rust
Google Cloud Functions9-60 phút32GB100ms-2sNode, Python, Java, Go, .NET
Azure Functions5-60 phút14GB200ms-5sNode, Python, Java, C#, PowerShell
Cloudflare Workers30s (free)128MB< 5msJS/TS, Wasm
Vercel Functions10-300s1-3GB100ms-1sNode, Python, Go, Ruby

Cold Start — Kẻ thù số một của Serverless

Cold start xảy ra khi platform phải tạo execution environment mới. Thời gian cold start phụ thuộc:

Cold Start = Runtime Init + Code Download + Dependency Loading + App Init

Ví dụ thực tế (ước lượng):
┌─────────────────┬───────────┬────────────┬──────────────┐
│ Runtime         │ Base Init │ 50MB deps  │ Total        │
├─────────────────┼───────────┼────────────┼──────────────┤
│ Node.js 20      │ 50-150ms  │ 100-300ms  │ 150-450ms    │
│ Python 3.12     │ 100-200ms │ 200-500ms  │ 300-700ms    │
│ Go              │ 10-50ms   │ N/A (binary)│ 10-80ms     │
│ Java 21 (JVM)   │ 500ms-2s  │ 500ms-2s   │ 1-4s         │
│ Java (GraalVM)  │ 50-100ms  │ 50-100ms   │ 100-200ms    │
│ Rust (Wasm)     │ 5-20ms    │ N/A        │ 5-30ms       │
└─────────────────┴───────────┴────────────┴──────────────┘

Chiến lược giảm Cold Start:

  • Provisioned concurrency: Giữ N instances warm (AWS Lambda). Chi phí: ~$5-15/tháng per instance.
  • Smaller bundles: Loại bỏ unused dependencies. Tree-shaking cho Node.js. Layer management cho Python.
  • Compiled languages: Go, Rust cold start nhanh hơn 10-50x so với Java/Python.
  • SnapStart (AWS): Snapshot JVM sau init → restore từ snapshot. Giảm Java cold start từ 3s xuống 200ms.

Edge Computing — Đưa compute đến gần user

Edge computing chạy code tại CDN edge nodes — hàng trăm locations trên toàn thế giới, cách user 10-50ms thay vì 200-500ms đến origin server.

Use cases phù hợp cho Edge:

  • A/B testing: Route users đến variants tại edge, không cần round-trip đến origin
  • Authentication: Validate JWT tokens tại edge → block unauthorized requests sớm
  • Geolocation routing: Redirect users đến server gần nhất dựa trên IP
  • Image/content transformation: Resize images, transform HTML cho mobile
  • API rate limiting: Enforce limits tại edge, bảo vệ origin servers

CDN Edge Functions — Platforms so sánh

PlatformRuntimeExecution LimitData StoreGlobal Locations
Cloudflare WorkersV8 Isolates10-30ms CPUKV, D1, R2300+
Vercel Edge FunctionsV8 Isolates25s wall timeEdge Config20+
AWS CloudFront FunctionsJS2ms CPU400+
AWS Lambda@EdgeNode/Python5-30sDynamoDB200+
Deno DeployV8/Deno50ms CPUDeno KV35+

V8 Isolates vs Containers: Cloudflare Workers và Vercel Edge dùng V8 Isolates — lightweight hơn containers 100x. Cold start < 5ms thay vì 100ms-5s. Trade-off: chỉ chạy JavaScript/TypeScript/Wasm, không thể dùng native binaries.

Vendor Lock-in — Rủi ro thực sự

Serverless code thường coupled chặt với platform-specific APIs:

Lock-in Spectrum:
Low lock-in ←──────────────────────────→ High lock-in

Cloudflare Workers   Vercel Functions   AWS Lambda + DynamoDB
(standard APIs)      (moderate)         + Step Functions + SQS
                                        + EventBridge + S3 triggers

Chiến lược giảm lock-in:

  • Business logic tách riêng khỏi platform adapter (Hexagonal Architecture)
  • Dùng standard APIs khi có thể (fetch, Web Streams, Web Crypto)
  • Abstraction layer cho platform services (database, queue, storage)
  • Nhưng thực tế: mức độ lock-in chấp nhận được tùy thuộc business context. Startup cần ship nhanh → lock-in OK. Enterprise long-term → cần abstraction layer.

Thực chiến

Tình huống: Image Optimization Pipeline — Vercel + Cloudflare

Bối cảnh: E-commerce platform, 2 triệu product images, users từ 10 quốc gia Đông Nam Á. Yêu cầu: resize/convert images on-the-fly (WebP, AVIF), latency < 100ms cho cached images, < 500ms cho uncached.

Mục tiêu: Giảm image load time 70%, giảm bandwidth cost 50%.

Architecture:

Request Flow:
User (Vietnam) → Cloudflare Edge (HCM) → Check cache
  ├── Cache HIT → Return cached image (10-30ms)
  └── Cache MISS → Cloudflare Worker:
       ├── Fetch original from R2 Storage
       ├── Resize + Convert to WebP/AVIF
       ├── Cache at edge (TTL: 7 days)
       └── Return to user (200-400ms first request)

Cloudflare Worker code flow:
1. Parse URL: /images/{id}?w=400&h=300&format=webp
2. Check KV cache for processed version
3. If miss: fetch original from R2, resize via cf.image API
4. Store processed version in KV (TTL: 7 days)
5. Return with Cache-Control headers

Kết quả đo được (ước lượng):

  • Image load time: 800ms → 45ms (cache hit), 400ms (cache miss)
  • Bandwidth: giảm 60% (WebP ~30% nhỏ hơn JPEG)
  • Chi phí: $200/tháng (Workers + R2) thay vì $800/tháng (dedicated image server)
  • Cache hit ratio: 92% sau tuần đầu

Tình huống: API Backend — Khi nào Serverless đắt hơn Server

Bối cảnh: REST API cho mobile app, 5 triệu DAU, average 50 requests/user/ngày = 250 triệu requests/ngày. Mỗi request trung bình 200ms execution, 256MB memory.

So sánh chi phí (ước lượng):

AWS Lambda:
  250M requests × $0.0000002/request = $50/ngày (requests)
  250M × 0.2s × 256MB = 12.8M GB-seconds
  12.8M × $0.0000166667 = $213/ngày (compute)
  Total: ~$263/ngày = ~$7.900/tháng

Dedicated EC2 (c6g.xlarge, 4 vCPU, 8GB RAM):
  250M requests/day ÷ 86.400s = 2.894 RPS
  Mỗi instance handle ~500 RPS (Go) = 6 instances
  6 × $0.136/hour × 24 × 30 = $5.875/tháng
  + Load balancer: $200/tháng
  + Ops overhead: ~$1.000/tháng (monitoring, patching)
  Total: ~$7.075/tháng

EKS với auto-scaling (2-10 instances):
  Average 4 instances × $0.136 × 24 × 30 = $3.917/tháng
  + EKS: $72/tháng + Ops: ~$1.500/tháng
  Total: ~$5.489/tháng

Phân tích: Ở 250M requests/ngày, Lambda đắt hơn EKS ~44%. Lambda hợp lý cho workloads < 50M requests/ngày hoặc traffic rất spiky (10x peak vs baseline). Crossover point (ước lượng): khoảng 100-150M requests/ngày, Lambda bắt đầu đắt hơn containers.

Tình huống: Real-time Personalization tại Edge — Cloudflare Workers

Bối cảnh: News platform, 5 triệu daily visitors từ 15 quốc gia. Cần personalize homepage dựa trên user preferences, location, và reading history. Origin server ở Singapore, users ở Vietnam, Indonesia, Philippines, Thailand.

Mục tiêu: Personalized content delivery < 100ms globally, giảm origin load 80%.

Architecture:

Edge Worker Logic:
1. Parse user cookie → extract user segment (anonymous/logged-in)
2. Determine geolocation (country, city) từ CF headers
3. Lookup personalization rules từ KV Store
4. Apply rules: reorder content blocks, inject local news section
5. Cache personalized variant tại edge (TTL: 5 min per segment+geo)
6. Return personalized HTML

Personalization Variants:
├── Anonymous + Vietnam → Default VN layout + trending VN news
├── Anonymous + Indonesia → Default ID layout + trending ID news  
├── Logged-in + Tech segment → Tech-first layout
└── Logged-in + Business segment → Business-first layout

Result: ~50 variants (5 segments × 10 geos) cached at edge

Kết quả (ước lượng):

  • Time to First Byte: 350ms (origin) → 25ms (edge cached)
  • Origin load: giảm 85% (chỉ handle cache misses + API calls)
  • Chi phí: $50/tháng (Workers + KV) vs $500/tháng (multiple origin servers for latency)

Sai lầm điển hình

Sai lầm 1: Dùng serverless cho long-running processes

Vấn đề: Chạy video transcoding (15-30 phút per job) trên AWS Lambda.

Tại sao sai: Lambda max timeout 15 phút. Job bị kill giữa chừng → wasted compute, incomplete output. Chi phí compute: Lambda charge per 100ms — video transcoding trên Lambda đắt hơn 5-10x so với EC2 spot instances.

ĐÚNG: Serverless cho trigger + orchestration, containers cho heavy processing. Ví dụ: Lambda nhận upload event → đẩy job vào SQS → ECS Fargate/EC2 Spot xử lý transcoding.

Sai lầm 2: Bỏ qua cold start impact cho user-facing APIs

Vấn đề: Java Lambda cho API endpoint, cold start 3-5 giây.

Tại sao sai: User đợi 3-5 giây cho request đầu tiên sau idle period. SLA P99 < 500ms → violated. Đặc biệt tệ cho APIs gọi từ mobile apps — users có thể nghĩ app bị lag.

ĐÚNG: Provisioned concurrency cho critical paths, hoặc chuyển sang Go/Rust (cold start < 100ms). Nếu dùng Java: SnapStart hoặc GraalVM native image. Hoặc đánh giá lại — API có traffic ổn định > 1 RPS thì serverless không optimal.

Sai lầm 3: Mỗi API endpoint là một Lambda function

Vấn đề: 50 Lambda functions, mỗi function cho một endpoint — /users, /orders, /products...

Tại sao sai: 50 functions = 50 cold start pools, 50 CI/CD pipelines, 50 monitoring dashboards. Shared code phải deploy dưới dạng Lambda Layer — thêm complexity. Cross-function debugging cực khó.

ĐÚNG: Group related endpoints vào ít Lambda functions hơn (1 function per domain/module). Hoặc dùng framework adapter: Express/Fastify app deploy như single Lambda qua serverless-http. Giảm cold start surface area.

Sai lầm 4: Edge function gọi database ở origin

Vấn đề: Edge function tại Tokyo gọi PostgreSQL ở US-East.

Tại sao sai: Edge function response 5ms, nhưng database round trip 200ms → total 205ms. Lợi ích edge computing bị triệt tiêu hoàn toàn. "Bạn đặt xe đẩy ở ngã tư nhưng mỗi lần bán phải chạy về kho trung tâm lấy nguyên liệu."

ĐÚNG: Edge functions kết hợp với edge-native data stores (Cloudflare KV/D1, DynamoDB Global Tables, PlanetScale). Hoặc chỉ dùng edge cho cache-able content và routing logic.

Under the Hood

Performance Analysis

ArchitectureLatency P50Latency P99Scaling SpeedCost Model
Dedicated Server5-20ms50-200msPhút (add instance)Fixed monthly
Container (K8s)5-20ms50-200ms10-60s (HPA)Per pod-hour
FaaS (warm)10-30ms50-100msMillisecondsPer invocation
FaaS (cold)100ms-5s1-10sN/APer invocation
Edge Function1-10ms10-50msInstant (global)Per request

Scaling Characteristics

FaaS Scaling: Truly elastic — 0 đến 1.000 concurrent instances trong seconds. Nhưng có concurrency limits: AWS Lambda default 1.000 concurrent, cần request increase. Burst limit: 500-3.000 concurrent instances/10 giây (tùy region).

Edge Scaling: Global by default — deploy 1 lần, chạy ở 300+ locations. Scaling limit: per-location concurrent requests (Cloudflare: hàng nghìn/location). Không có "scale to zero" concern — V8 isolates startup < 5ms.

Cost at Scale (ước lượng, monthly):

Requests/thángLambda (256MB, 200ms)Cloudflare WorkersEC2 Auto-scaling
1 triệu$0.60$5 (included)$50+ (min 1 instance)
10 triệu$6$5$50+
100 triệu$60$5-50$200-500
1 tỷ$600$50-500$500-1.500
10 tỷ$6.000$500-5.000$1.500-5.000

Trade-offs Decision Matrix

Tiêu chíChọn Serverless khi...Chọn Containers khi...Chọn Edge khi...
Traffic patternSpiky, unpredictableSteady, predictableGlobal, latency-sensitive
Execution time< 15 phút> 15 phút< 30 giây
Cost priorityMinimize idle costMinimize per-request costMinimize latency
Team sizeNhỏ (no DevOps)Có platform teamNhỏ-medium
Lock-in toleranceHigh (startup)Low (enterprise)Medium

Serverless Security Considerations

Attack surface đặc thù:

  • Event injection: Malicious payloads trong event sources (S3 object names, API Gateway parameters). Phải validate và sanitize tất cả inputs — serverless không miễn nhiễm với injection attacks.
  • Dependency vulnerabilities: Node.js Lambda với 200+ dependencies → attack surface lớn. Dùng npm audit, minimize dependencies.
  • IAM over-permission: Lambda function được gắn IAM role quá rộng (full S3 access thay vì chỉ 1 bucket). Principle of least privilege — mỗi function chỉ có permissions cần thiết.
  • Secret management: Không hardcode secrets trong code. Dùng AWS Secrets Manager, Cloudflare Secrets, hoặc Vercel Environment Variables (encrypted).

Observability cho Serverless

Thách thức: Distributed functions, ephemeral instances, no persistent logs by default.

Stack đề xuất:

  • Tracing: AWS X-Ray, Datadog APM — trace request xuyên suốt API Gateway → Lambda → DynamoDB
  • Metrics: CloudWatch custom metrics — invocation count, duration, errors, throttles
  • Logging: Structured JSON logs → CloudWatch Logs → forwarded to centralized system (Datadog, ELK)
  • Alerting: Duration P99 > threshold, error rate > 1%, concurrent executions > 80% limit

Checklist ghi nhớ

✅ Checklist triển khai

Serverless Assessment

  • [ ] Traffic pattern phân tích: spiky hay steady?
  • [ ] Execution time dưới platform limits (15 phút cho Lambda)
  • [ ] Cold start impact chấp nhận được cho use case
  • [ ] Chi phí tính toán so với containers ở expected traffic
  • [ ] Vendor lock-in assessment: abstraction layer cần thiết?

Cold Start Optimization

  • [ ] Bundle size tối ưu (tree-shaking, remove unused deps)
  • [ ] Runtime phù hợp (Go/Rust cho latency-sensitive paths)
  • [ ] Provisioned concurrency cho critical user-facing APIs
  • [ ] Connection pooling strategy (RDS Proxy, PgBouncer)

Edge Computing

  • [ ] Data locality: edge data store hay chỉ cache?
  • [ ] Compute constraints kiểm tra (CPU time, memory limits)
  • [ ] Cache invalidation strategy defined
  • [ ] Fallback plan khi edge function fail (route to origin)

Production Readiness

  • [ ] Monitoring và alerting configured (invocation errors, duration, throttles)
  • [ ] Dead Letter Queue cho failed invocations
  • [ ] Retry logic với idempotency
  • [ ] Load testing ở expected peak (verify concurrency limits)

Bài tập luyện tập

Bài 1: Architecture Decision — Intermediate

Đề bài: Startup xây dựng URL shortener (giống Bitly). Requirements: 1.000 URL creates/ngày (write), 1 triệu redirects/ngày (read), latency redirect < 50ms, global users. Team: 2 backend engineers. Đề xuất architecture (serverless, containers, edge, hoặc hybrid) và giải thích lý do.

🧠 Quiz

Câu hỏi kiểm tra: Cho URL shortener với 1M redirects/ngày global, architecture nào phù hợp nhất?

  • [ ] A. Single EC2 instance + PostgreSQL
  • [ ] B. AWS Lambda cho cả create và redirect
  • [x] C. Edge function (Cloudflare Workers + KV) cho redirect, serverless cho create
  • [ ] D. Kubernetes cluster multi-region Giải thích: Redirect cần latency < 50ms globally → edge function + KV store là optimal (< 10ms). Create traffic thấp (1.000/ngày) → serverless function đủ. Option A: single region = high latency cho global users. Option B: Lambda cold start > 50ms target. Option D: overkill cho team 2 người.
✅ Lời giải chi tiết
Architecture: Hybrid Edge + Serverless

Write Path (Create Short URL):
├── API: Vercel Serverless Function (Node.js)
├── Database: PlanetScale (global MySQL)
├── Generate short code, store mapping
└── Replicate to Cloudflare KV (async)

Read Path (Redirect):
├── Cloudflare Worker (300+ edge locations)
├── Lookup short code in Cloudflare KV (< 5ms)
├── 302 Redirect to original URL
└── Fallback: query PlanetScale if KV miss

Analytics:
├── Cloudflare Worker logs click events
├── Batch write to Analytics Engine (per-request)
└── Dashboard: Grafana + ClickHouse

Chi phí ước lượng:
├── Cloudflare Workers: $5/tháng (10M requests included)
├── Cloudflare KV: $5/tháng
├── PlanetScale: $29/tháng
├── Vercel: $20/tháng
└── Total: ~$59/tháng cho 1M redirects/ngày

Bài 2: Cold Start Analysis — Intermediate

Đề bài: API endpoint hiện chạy trên Java Lambda, cold start P99: 4.2 giây, warm invocation: 50ms. SLA yêu cầu P99 < 500ms. Đề xuất 3 giải pháp, phân tích trade-offs của mỗi giải pháp.

💡 Gợi ý
  • Provisioned concurrency: giải quyết ngay nhưng tăng cost
  • Chuyển runtime (Go, Node.js): giảm cold start nhưng cần rewrite
  • SnapStart: Java-specific, giảm cold start nhưng có limitations
✅ Lời giải chi tiết
Giải pháp 1: Provisioned Concurrency
├── Giữ 5 warm instances 24/7
├── Cold start: 0 (instances luôn warm)
├── Cost: 5 × $0.015/hour × 24 × 30 = $54/tháng thêm
├── Trade-off: Trả tiền idle, scaling vẫn cold cho burst > 5
└── Verdict: Quick fix, không giải quyết root cause

Giải pháp 2: Migrate to Go
├── Cold start: 10-80ms (vs 4.2s Java)
├── Effort: 2-4 tuần rewrite
├── Trade-off: Team phải học Go, Java libraries không dùng được
└── Verdict: Best long-term nếu team willing

Giải pháp 3: Java SnapStart
├── Cold start: 200-400ms (vs 4.2s)
├── Effort: Config change + code adjustments
├── Trade-off: Không hỗ trợ provisioned concurrency cùng lúc,
│   limitations với certain libraries (random, connections)
└── Verdict: Best quick win cho Java team

Recommended: Giải pháp 3 (ngắn hạn) + Giải pháp 2 (dài hạn)

Bài 3: Edge Computing Design — Advanced

Đề bài: Thiết kế A/B testing system chạy trên edge. Requirements: 100% traffic routing tại edge (không round-trip origin), support 50 concurrent experiments, < 5ms routing decision, consistent user experience (cùng user luôn thấy cùng variant).

🧠 Quiz

Câu hỏi: Để đảm bảo consistent A/B assignment (cùng user luôn thấy cùng variant), phương pháp nào phù hợp nhất tại edge?

  • [ ] A. Lưu assignment trong database, query mỗi request
  • [x] B. Deterministic hash: hash(user_id + experiment_id) % 100
  • [ ] C. Lưu assignment trong cookie, gửi mỗi request
  • [ ] D. Random assignment, lưu trong edge KV store Giải thích: Deterministic hash không cần external storage (< 1ms compute), consistent across tất cả edge locations, không cần cookie. Option A: database query triệt tiêu edge benefit. Option C: hoạt động nhưng tăng request size, không work cho API calls. Option D: KV eventual consistency có thể gây inconsistency giữa edge locations.
✅ Lời giải chi tiết
Architecture: Edge A/B Testing

Config Distribution:
├── Admin UI → Config API (origin)
├── Config API → Cloudflare KV (experiment configs)
│   Key: "experiments" → JSON array of 50 experiments
│   Each: {id, name, variants: [{id, weight}], targetRules}
└── KV propagation: < 60s globally

Edge Worker Logic (per request):
1. Read experiment configs from KV (cached in worker memory)
2. For each active experiment:
   a. Check target rules (URL, geo, user segment)
   b. hash(user_id + experiment_id) % 100
   c. Map hash to variant based on weights
3. Set response headers: X-Experiments: {"exp1":"B","exp2":"A"}
4. Modify response (inject script, route to variant page)
5. Log assignment event (async, batch)

Latency: Config read (cached): < 1ms
         Hash computation (50 experiments): < 2ms
         Total routing decision: < 3ms

Liên kết học tiếp

Từ khóa glossary: serverless, FaaS, function as a service, cold start, warm start, provisioned concurrency, edge computing, CDN edge functions, V8 isolates, Cloudflare Workers, Vercel Edge, Lambda, vendor lock-in, pay-per-use

Tìm kiếm liên quan: serverless là gì, cold start giải pháp, edge computing use cases, so sánh chi phí serverless vs containers, Cloudflare Workers tutorial