Introduction
A sudden traffic spike that triples your request rate in a minute can either burn your budget or crash your service, depending on the runtime model you chose. Serverless functions pay per‑invocation and scale instantly, but cold starts add latency; containerized microservices keep warm instances, incur steady compute cost, and give you full control over the runtime. The choice hinges on three dimensions: raw performance, total cost of ownership, and operational complexity.
#How it works
flowchart LR
A["Client (HTTPS)"] --> B["API Gateway (REST)"]
B --> C["Lambda (Node.js)"]
C --> D["DynamoDB (NoSQL)"]
B --> E["Ingress (NGINX)"]
E --> F["K8s Service (ClusterIP)"]
F --> G["Pod (Go microservice)"]
G --> H["PostgreSQL (RDS)"]
Left side: pure serverless path – API Gateway triggers a Lambda that talks directly to a managed NoSQL store.
Right side: containerized path – API Gateway forwards to an Ingress controller, which routes to a Kubernetes Service and a set of Pods that query a relational DB. Both paths share the same client entry point, making the comparison fair.
#Setting it up
#1. Provision the shared resources
provider "aws" {
region = "us-east-1"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_rds_instance" "pg" {
engine = "postgres"
instance_class = "db.t3.micro"
allocated_storage = 20
username = "admin"
password = "ChangeMe123!"
skip_final_snapshot = true
}
Note
The Terraform snippet creates a VPC and a tiny PostgreSQL instance for the containerized side. Adjust instance_class to match your load; db.t3.micro costs about $0.017 / hour (AWS pricing, 2026).
#2. Serverless stack (AWS SAM)
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
Api:
Type: AWS::Serverless::Api
Properties:
StageName: prod
HelloFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: nodejs20.x
Handler: index.handler
CodeUri: src/
MemorySize: 256
Timeout: 10
Events:
ApiEvent:
Type: Api
Properties:
Path: /hello
Method: get
RestApiId: !Ref Api
sam build
sam deploy --guided
Tip
Set MemorySize to the smallest value that meets your latency target; Lambda pricing is $0.00001667 per GB‑second (2026).
#3. Containerized microservice (Kubernetes)
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-go
spec:
replicas: 3
selector:
matchLabels:
app: hello-go
template:
metadata:
labels:
app: hello-go
spec:
containers:
- name: hello-go
image: ghcr.io/azad25/hello-go:1.0.0
ports:
- containerPort: 8080
resources:
requests:
cpu: "250m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
---
apiVersion: v1
kind: Service
metadata:
name: hello-go-svc
spec:
selector:
app: hello-go
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
kubectl apply -f deployment.yaml
Important
Use a horizontal pod autoscaler (HPA) to match the serverless scaling curve. Example HPA (not shown) can scale from 2 to 20 pods based on CPU > 70 %.
#Running it in production
#Monitoring
| Component | Metric | Tool |
|---|---|---|
| Lambda | Invocations, Duration, Errors | CloudWatch |
| Pods | CPU, Memory, Request Latency | Prometheus + Grafana |
| API GW / Ingress | 4xx/5xx, Latency | CloudWatch / NGINX Exporter |
| DB | Connections, QPS, Read/Write latency | RDS Performance Insights / DynamoDB Metrics |
- Set an alert on Lambda cold‑start latency > 500 ms; a spike often signals a new version rollout or insufficient provisioned concurrency.
- For containers, watch pod restart rate; a sudden rise usually means OOM kills or failing health checks.
#Failure modes
| Scenario | Serverless impact | Containerized impact |
|---|---|---|
| Regional outage (AWS us-east-1) | All Lambdas unavailable; fallback to another region via Route 53 health‑checks | Pods in the same region go down; can survive if you run a multi‑region EKS cluster or use a secondary cluster |
| Cold start surge | Latency spikes for first 10‑20 requests per new instance | No cold start, but scaling lag (HPA evaluation period) can cause queue buildup |
| Dependency version mismatch | New Lambda package may break at runtime; need to redeploy whole function | Rolling update can be staged pod‑by‑pod, reducing risk |
#Cost comparison (2026 pricing, US East)
| Item | Serverless (per 1 M requests, avg 200 ms) | Containerized (per month, 3 pods) |
|---|---|---|
| Compute | $0.20 (256 MB × 200 ms) | $0.017 / hour × 24 × 30 ≈ $12.24 |
| Request overhead | $0.40 (first 1 M free, then $0.40 / M) | No per‑request charge |
| Managed DB (DynamoDB) | $1.25 (5 RCU, 5 WCU) | $0.018 / hour for db.t3.micro ≈ $13.00 |
| Total (approx.) | $0.60 for bursty traffic | $25–30 for steady 100 RPS load |
Note
Serverless wins when traffic is highly variable and average utilization stays below ~30 %. Containers become cheaper once you sustain > 150 RPS continuously, because the fixed compute cost is amortized.
#Common pitfalls
- Under‑estimating cold start latency – especially for Java or .NET runtimes. Mitigate with Provisioned Concurrency or by keeping the function warm via a scheduled “ping” Lambda.
- Missing IAM least‑privilege policies – serverless functions often run with overly broad roles; tighten to only the tables/APIs they need.
- Over‑provisioning pods – setting replica count too high inflates cost without measurable latency benefit. Use HPA with realistic min/max values.
- Ignoring network egress – both models incur data transfer fees; a high‑throughput API can add $0.09 / GB (AWS). Keep payloads small and enable gzip compression at the gateway.
- Logging overload – Lambda logs go to CloudWatch automatically; uncontrolled log volume can cost $0.50 / GB. For containers, ship logs to a central Loki/Promtail pipeline and set retention policies.
#Key takeaways
- Performance: Serverless offers instant scale but suffers from cold starts; containers provide stable latency at the cost of warm‑instance overhead.
- Cost: Serverless is cheaper for spiky, low‑average traffic; containers become economical for sustained high throughput.
- Operational complexity: Serverless reduces infra management (no servers, no patches) but adds vendor‑lock‑in and cold‑start tuning; containers demand orchestration, monitoring, and patching but grant full control over runtime and networking.
- Hybrid approach: Use serverless for edge‑triggered, low‑volume endpoints (webhooks, auth) and containers for core, high‑throughput services.
- Monitoring matters: Track cold‑start latency, pod restarts, and DB metrics to catch the moment your chosen model starts to bleed cost or reliability.

Comments
No comments yet. Start the conversation.