Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:25:52 +08:00
commit e840c60a06
19 changed files with 6852 additions and 0 deletions

267
commands/lambda-cost.md Normal file
View File

@@ -0,0 +1,267 @@
---
description: Deep dive into Lambda cost optimization strategies for Rust functions
---
You are helping the user optimize the cost of their Rust Lambda functions.
## Your Task
Guide the user through advanced cost optimization techniques using AWS Lambda Power Tuning, memory configuration, and Rust-specific optimizations.
## Lambda Pricing Model
**Cost = (Requests × $0.20 per 1M) + (GB-seconds × $0.0000166667)**
- **Requests**: $0.20 per 1 million requests
- **Duration**: Charged per GB-second
- 1 GB-second = 1 GB memory × 1 second execution
- ARM64 (Graviton2): 20% cheaper than x86_64
**Example**:
- 512 MB, 100ms execution, 1M requests/month
- Duration: 0.5 GB × 0.1s × 1M = 50,000 GB-seconds
- Cost: $0.20 + (50,000 × $0.0000166667) = $0.20 + $0.83 = $1.03
## Memory vs CPU Allocation
Lambda allocates CPU proportional to memory:
- **128 MB**: 0.08 vCPU
- **512 MB**: 0.33 vCPU
- **1024 MB**: 0.58 vCPU
- **1769 MB**: 1.00 vCPU (full core)
- **3008 MB**: 1.77 vCPU
- **10240 MB**: 6.00 vCPU
**Key insight**: More memory = more CPU = faster execution = potentially lower cost
## AWS Lambda Power Tuning Tool
Automatically finds optimal memory configuration.
### Setup
```bash
# Deploy Power Tuning (one-time)
git clone https://github.com/alexcasalboni/aws-lambda-power-tuning
cd aws-lambda-power-tuning
sam deploy --guided
# Run power tuning
aws stepfunctions start-execution \
--state-machine-arn arn:aws:states:REGION:ACCOUNT:stateMachine:powerTuningStateMachine \
--input '{
"lambdaARN": "arn:aws:lambda:REGION:ACCOUNT:function:my-rust-function",
"powerValues": [128, 256, 512, 1024, 1536, 2048, 3008],
"num": 10,
"payload": "{\"test\": \"data\"}",
"parallelInvocation": true,
"strategy": "cost"
}'
```
**Strategies**:
- `cost`: Minimize cost
- `speed`: Minimize duration
- `balanced`: Balance cost and speed
## Rust-Specific Optimizations
### 1. Binary Size Reduction
**Cargo.toml**:
```toml
[profile.release]
opt-level = 'z' # Optimize for size
lto = true # Link-time optimization
codegen-units = 1 # Single codegen unit
strip = true # Strip symbols
panic = 'abort' # Smaller panic handler
[profile.release.package."*"]
opt-level = 'z' # Optimize dependencies too
```
**Result**: 3-5x smaller binary = faster cold starts = lower duration
### 2. Use ARM64 (Graviton2)
```bash
cargo lambda build --release --arm64
cargo lambda deploy --arch arm64
```
**Savings**: 20% lower cost for same performance
### 3. Dependency Optimization
```bash
# Analyze binary size
cargo install cargo-bloat
cargo bloat --release -n 20
# Find unused features
cargo install cargo-unused-features
cargo unused-features
# Remove unused dependencies
cargo install cargo-udeps
cargo +nightly udeps
```
**Example**:
```toml
# ❌ Full tokio (heavy)
tokio = { version = "1", features = ["full"] }
# ✅ Only needed features (light)
tokio = { version = "1", features = ["macros", "rt"] }
```
### 4. Use Lightweight Alternatives
- `ureq` instead of `reqwest` for simple HTTP
- `rustls` instead of `native-tls`
- `simdjson` instead of `serde_json` for large JSON
- Avoid `regex` for simple string operations
## Memory Configuration Strategies
### Strategy 1: Start Low, Test Up
```bash
# Test different memory sizes
for mem in 128 256 512 1024 2048; do
echo "Testing ${mem}MB"
cargo lambda deploy --memory $mem
# Run load test
# Measure duration and cost
done
```
### Strategy 2: Monitor CloudWatch Metrics
```bash
# Get duration statistics
aws cloudwatch get-metric-statistics \
--namespace AWS/Lambda \
--metric-name Duration \
--dimensions Name=FunctionName,Value=my-function \
--start-time 2025-01-01T00:00:00Z \
--end-time 2025-01-02T00:00:00Z \
--period 3600 \
--statistics Average,Maximum
# Get memory usage
aws cloudwatch get-metric-statistics \
--namespace AWS/Lambda \
--metric-name MemoryUtilization \
--dimensions Name=FunctionName,Value=my-function \
--start-time 2025-01-01T00:00:00Z \
--end-time 2025-01-02T00:00:00Z \
--period 3600 \
--statistics Maximum
```
### Strategy 3: Right-size Based on Workload
**IO-intensive** (API calls, DB queries):
- Start: 512 MB
- Sweet spot: Usually 512-1024 MB
- Reason: Limited by network, not CPU
**Compute-intensive** (data processing):
- Start: 1024 MB
- Sweet spot: Usually 1769-3008 MB
- Reason: More CPU = faster = lower total cost
**Mixed workload**:
- Start: 1024 MB
- Test: 1024, 1769, 2048 MB
- Use Power Tuning tool
## Cost Optimization Checklist
- [ ] Use ARM64 architecture (20% savings)
- [ ] Optimize binary size (faster cold starts)
- [ ] Remove unused dependencies
- [ ] Use lightweight alternatives
- [ ] Run AWS Lambda Power Tuning
- [ ] Right-size memory based on workload
- [ ] Set appropriate timeout (not too high)
- [ ] Reduce cold starts (keep functions warm if needed)
- [ ] Use reserved concurrency for predictable workloads
- [ ] Batch requests when possible
- [ ] Cache results (DynamoDB, ElastiCache)
- [ ] Monitor and alert on cost anomalies
## Advanced: Provisioned Concurrency
For latency-sensitive functions, pre-warm instances.
**Cost**: $0.015 per GB-hour (expensive!)
```bash
aws lambda put-provisioned-concurrency-config \
--function-name my-function \
--provisioned-concurrent-executions 5
```
**Use when**:
- Cold starts are unacceptable
- Predictable traffic patterns
- Cost justifies latency improvement
## Cost Monitoring
### CloudWatch Billing Alerts
```bash
aws cloudwatch put-metric-alarm \
--alarm-name lambda-cost-alert \
--alarm-description "Alert when Lambda costs exceed threshold" \
--metric-name EstimatedCharges \
--namespace AWS/Billing \
--statistic Maximum \
--period 21600 \
--evaluation-periods 1 \
--threshold 100 \
--comparison-operator GreaterThanThreshold
```
### Cost Explorer Tags
```bash
cargo lambda deploy \
--tags Environment=production,Team=backend,CostCenter=engineering
```
## Real-World Optimization Example
**Before**:
- Memory: 128 MB
- Duration: 2000ms
- Requests: 10M/month
- Cost: $0.20 + (0.128 GB × 2s × 10M × $0.0000166667) = $42.87/month
**After Optimization**:
- Binary size: 8MB → 2MB (cold start: 800ms → 300ms)
- Architecture: x86_64 → ARM64 (20% cheaper)
- Memory: 128 MB → 512 MB (duration: 2000ms → 600ms)
- Duration improvement: More CPU = faster execution
**Cost calculation**:
- Compute: 0.512 GB × 0.6s × 10M × $0.0000166667 × 0.8 (ARM discount) = $40.96
- Requests: $0.20
- **Total**: $41.16/month (4% savings with better performance!)
**Key lesson**: Sometimes more memory = lower total cost due to faster execution.
## Rust Performance Advantage
Rust vs Python/Node.js:
- **3-4x cheaper** on average
- **3-10x faster execution**
- **2-3x faster cold starts**
- **Lower memory usage**
Guide the user through cost optimization based on their workload and budget constraints.