# Exercise 3: Lambda Cost, Concurrency and Cold Starts — Do the Math

Use `aws_lambda_and_serverless_theory_1.md` and `_theory_2.md`. Show calculations. Prices (approximate, eu-west-1): requests $0.20 per million; compute $0.0000166667 per GB-s (x86), $0.0000133334 (arm64); provisioned concurrency ~$0.0000041667 per GB-s provisioned + reduced compute rate (assume $0.0000097222 per GB-s on arm64).

## Workload

`image-api` resizes images on demand:
- 30 million requests/month; average duration 400 ms at 1,024 MB (x86).
- Traffic peaks at 900 requests/second for ~2 hours per day; otherwise ~50 req/s.
- p99 cold start: 1.8 s (bundle 48 MB including the full AWS SDK and `sharp` binaries).
- It reads image metadata from an RDS PostgreSQL instance with `max_connections = 200`.

## Deliverables

1. **Monthly cost** today (requests + compute). Then recompute after moving to **arm64** (same duration) and after Power Tuning shows 2,048 MB cuts duration to 180 ms. Which configuration is cheapest?
2. **Peak concurrency** at 900 req/s using Little's law (`advanced-engineering/advanced/05-performance_optimization_and_bottlenecks`) with 400 ms and with 180 ms. Will the default account limit of 1,000 suffice? What else shares that limit?
3. **Database risk**: what happens to RDS at peak? Propose two fixes and their effect on concurrency/cost.
4. **Cold starts**: list three ways to reduce the 1.8 s p99 (bundle, runtime, init code), and compute the monthly cost of **provisioned concurrency** of 100 environments at 2,048 MB on arm64 for the 2 peak hours/day only (scheduled with Application Auto Scaling) vs 24/7.
5. **Container alternative**: estimate whether 6 always-on Fargate tasks (1 vCPU / 2 GB, ~$0.04048/vCPU-h and ~$0.004445/GB-h) handling the base load + Lambda for the peak would be cheaper. State your assumptions.

## Requirements Checklist

- [ ] Today: 30M × 0.4 s × 1 GB = 12M GB-s × $0.0000166667 ≈ $200 + $6 requests.
- [ ] arm64 same duration ≈ $160 + $6; 2,048 MB / 180 ms arm64: 30M × 0.18 × 2 = 10.8M GB-s ≈ $144 + $6 → cheapest and faster.
- [ ] Concurrency = 900 × 0.4 = 360 (or 900 × 0.18 = 162); fits under 1,000 but shared with all functions in the account/region; reserved concurrency considered.
- [ ] RDS: 360 environments × ≥1 connection > 200 → RDS Proxy and/or maximum/reserved concurrency cap, caching metadata.
- [ ] Cold-start fixes: esbuild + SDK v3 modular imports, move `sharp` to a layer/arm64 build, lazy init, provisioned concurrency/SnapStart.
- [ ] Provisioned concurrency math: 100 × 2 GB × 7,200 s/day × 30 ≈ 43.2M GB-s provisioned ≈ $180/month for peak hours vs ~$2,160 for 24/7 (state assumptions).
- [ ] The Fargate comparison is computed and concludes with a reasoned recommendation.
