Serverless Cost Engineering
Optimize serverless costs across Lambda, API Gateway, DynamoDB, and managed services. Covers pricing models, invocation optimization, cold start economics, memory tuning, and the hidden costs that make serverless more expensive than expected.
Serverless promises “pay only for what you use.” In practice, serverless costs can spiral quickly if you do not understand the pricing model. A Lambda function that runs for 1 second at 1GB memory costs $0.0000167 per invocation — trivial in isolation, catastrophic at 100 million invocations per month.
Lambda Cost Anatomy
Lambda pricing = Requests + Duration + Memory
Requests: $0.20 per 1 million requests
Duration: $0.0000166667 per GB-second
Example: 10M invocations/month, 500ms average, 512MB memory
Requests: 10M × $0.20/1M = $2.00
Duration: 10M × 0.5s × 0.5GB × $0.0000166667 = $41.67
Total: $43.67/month
Memory-Duration Trade-Off
Lambda CPU scales linearly with memory. More memory = more CPU = faster execution:
128MB memory: 1200ms average → Cost: $0.0000025
256MB memory: 800ms average → Cost: $0.0000033
512MB memory: 450ms average → Cost: $0.0000038
1024MB memory: 250ms average → Cost: $0.0000042
# 512MB is often the sweet spot — faster execution offsets higher memory cost
AWS Lambda Power Tuning
# Deploy the power tuning state machine
aws serverless deploy --template power-tuning.yml
# Run optimization
aws stepfunctions start-execution \
--state-machine-arn arn:aws:states:...:power-tuning \
--input '{"lambdaARN":"arn:aws:lambda:...:myFunction","num":50,"powerValues":[128,256,512,1024,2048]}'
API Gateway Costs
REST API: $3.50 per million requests
HTTP API: $1.00 per million requests (71% cheaper)
WebSocket: $1.00 per million messages
Recommendation: Use HTTP API unless you need REST-specific features
(request validation, usage plans, API keys, caching)
DynamoDB Cost Optimization
Capacity Modes
On-Demand:
- $1.25 per million write requests
- $0.25 per million read requests
- Best for: unpredictable, spiky traffic
Provisioned:
- $0.00065 per WCU per hour
- $0.00013 per RCU per hour
- Best for: predictable, steady traffic
- 70-80% cheaper than on-demand at scale
Reserved Capacity (Provisioned):
- 1-year or 3-year commitment
- Additional 50-75% discount
Data Modeling for Cost
# BAD: Full table scan
response = table.scan()
# GOOD: Query with partition key
response = table.query(
KeyConditionExpression=Key('pk').eq('USER#123')
)
# Reads only the items you need, costs proportional to data returned
Hidden Serverless Costs
| Hidden Cost | Example | Mitigation |
|---|---|---|
| CloudWatch Logs | 10M logs × 1KB = 10 GB ingestion = $5.00 | Filter logs, reduce verbosity |
| Data Transfer | Cross-AZ, cross-region, internet egress | Keep services in same AZ |
| NAT Gateway | Lambda in VPC: $0.045/hr + $0.045/GB | Use VPC endpoints instead |
| Step Functions | $0.025 per 1,000 state transitions | Use Express workflows for high-volume |
| S3 API calls | LIST: $5 per 1M, GET: $0.40 per 1M | Cache, batch, minimize API calls |
Cost Monitoring for Serverless
# Tag all serverless resources for cost allocation
resource_tags = {
"Team": "order-team",
"Service": "order-processor",
"Environment": "production",
"CostCenter": "CC-1234"
}
# Monitor per-function costs
# Create CloudWatch dashboard with:
# - Invocations per function
# - Duration per function
# - Concurrent executions
# - Throttles (indicates need for more capacity)
Anti-Patterns
| Anti-Pattern | Consequence | Fix |
|---|---|---|
| Lambda for constant traffic | 3-5x more expensive than containers | Use ECS/Fargate for sustained load |
| Default 128MB memory | Slow execution, often more expensive | Power-tune every function |
| On-demand DynamoDB at scale | Paying premium for predictable traffic | Switch to provisioned with auto-scaling |
| Logging everything in production | CloudWatch costs exceed Lambda costs | Structured logging with sampling |
| No cost tagging on functions | Cannot attribute serverless costs | Tag every function by team/service |
Serverless is not always cheaper. It is always more granular — you pay exactly for usage, which can be more or less than fixed infrastructure depending on your traffic pattern.