Posted my first serious serverless app to production last month. Ran what I thought was a clean, event-driven architecture on a major cloud provider. The projected cost from the pricing calculator was negligible.
The actual bill was 22x higher.
I'm used to reviewing vendor invoices line by line, so I did a full breakdown. The architecture was straightforward:
* API Gateway
* Lambda functions (four, all under 512MB memory, average 300ms execution)
* DynamoDB for primary data
* S3 for asset storage
* CloudWatch for logs (my mistake)
The culprits, in order of impact:
1. **DynamoDB Read Capacity Units (RCUs).** I used on-demand mode thinking it was simpler. The sporadic but high-volume read patterns led to massive charges. Provisioned capacity with auto-scaling would have been 60% cheaper for this pattern.
2. **API Gateway.** HTTP API, not REST. The cost per million requests adds up faster than you think when you have chatty client-side logic. No caching layer was a critical oversight.
3. **CloudWatch Logs.** The Lambda functions were verbose for debugging. Storing and ingesting those logs, especially with a few retry storms, was equivalent to 40% of the compute cost itself.
4. **S3 GET requests.** Similar to API Gateway. Each client session generated hundreds of small object operations.
The serverless promise of "pay-per-use" is valid, but "use" includes every single transaction and request, not just compute time. My design had high transaction volume per user action.
Looking for concrete review from others who have optimized in production:
* Is moving Lambda to provisioned concurrency for baseline traffic actually cost-effective, or does it defeat the purpose?
* For internal APIs, is a simple ALB + Fargate setup now more predictable than API Gateway + Lambda once you cross a certain request threshold?
* Which monitoring tools did you settle on to avoid CloudWatch data ingestion fees? I need logs for compliance but the current volume is unsustainable.
Where is your SOC 2?
Your breakdown is spot on, especially about DynamoDB on-demand. That pricing model is a trap for spiky workloads. Even with auto-scaling on provisioned capacity, you need to watch the scaling rates. It can lag behind a sudden surge, causing throttling unless you've built in a buffer.
For the API Gateway costs, placing a CloudFront distribution in front can help immensely. It caches at the edge and turns those chatty requests into cheap cache hits. I'd also look at consolidating client-side calls into fewer, coarser-grained endpoints if possible.
sub-100ms or bust
Good point about the CloudFront trick. I've used that to cut API Gateway costs by caching static responses from a simple lead-capture endpoint.
But that buffer for DynamoDB scaling is a real pain to get right. We set up auto-scaling with a 50% buffer and still got throttled during a flash sale promo. The scaling action just took too long. Ended up having to over-provision for the "peak" hours manually. Kinda defeats the purpose.
Trial number 47 this year.