Writing7 AWS Serverless Mistakes That Silently Inflate Your Cloud Bill — LinkIT
5 min readaws, serverless, cost, lambda, cloud-infrastructure

7 AWS Serverless Mistakes That Silently Inflate Your Cloud Bill

Review AWS serverless cost drivers: Lambda sizing, API selection, DynamoDB capacity, connection reuse, logging, and budget alerts.

Serverless costs depend on more than request volume. Memory settings, API choices, database capacity, retries, and logging can all increase a bill without adding useful work.

Review these seven configuration and design choices when investigating AWS serverless spend.

Mistake 1: Leaving Lambda Memory at the Default

Leaving Lambda at a low memory allocation can increase cost in two ways:

First, 128MB gives your function minimal CPU. Slow execution means more billed milliseconds per invocation.

Second — and counter-intuitively — a higher memory allocation often costs less in total. Because Lambda billing is duration × memory, a function that runs in 200ms at 512MB may cost less than the same function running in 900ms at 128MB.

Fix: Run AWS Lambda Power Tuning against your functions. It tests multiple memory configurations and reports the cost-optimal setting. Do this for any function running more than a few thousand invocations per day.

Mistake 2: Using REST API Gateway When HTTP API Suffices

Compare current regional prices and feature requirements for API Gateway REST and HTTP APIs. Check authorization, validation, caching, and integration needs before choosing the cheaper option.

REST API features you likely do not need: request/response body transformation with mapping templates, usage plans with API keys, and AWS WAF integration at the API level (which you can add with CloudFront instead).

Fix: Audit your REST APIs. For each one, check whether you are using any REST-only features. If not, migrate to HTTP API. The Terraform or CloudFormation change is small; the bill reduction is immediate.

Mistake 3: DynamoDB On-Demand for Steady-State Tables

DynamoDB On-Demand is priced for unpredictability. It is the right choice when you genuinely cannot forecast read/write volume. It is the wrong choice for tables with stable, predictable traffic — and using it there costs roughly 6-7x more than provisioned capacity.

A table with 10 million reads and 2 million writes per month costs meaningfully less on provisioned capacity with auto-scaling than On-Demand, once traffic patterns are established.

Fix: After a table has two or more weeks of CloudWatch metrics, evaluate whether the traffic pattern is forecastable. If it is, switch to provisioned capacity with auto-scaling set to maintain 70% target utilization. Keep On-Demand for development environments and genuinely irregular batch tables.

Mistake 4: Initializing Clients and Connections Inside the Handler

Every AWS SDK client, database connection, or third-party API wrapper initialized inside the Lambda handler runs on every invocation. Moving initialization to module scope runs it once per execution environment, shared across all warm invocations.

At modest traffic — say, 5 million invocations per month — a 50ms connection setup inside the handler adds 250,000 seconds of billed compute. Outside the handler, that cost collapses to the number of cold starts.

Fix: Move all client initialization to module scope. This is one of the highest-ROI code changes you can make, and it also improves p50 response latency.

Mistake 5: No Concurrency Limits on Lambda

Without concurrency limits, a traffic spike, a retry storm, or a misconfigured event source can drive Lambda invocations to thousands per second. Each invocation bills independently. Lambda's default account-level concurrency limit (typically 1,000) provides some protection, but:

  • That limit is shared across all functions in a region
  • Reserved concurrency of zero is the only way to ensure a function cannot consume shared capacity unexpectedly
  • Unreserved concurrency can allow a single function to starve all other functions in the same account

Fix: Set reserved concurrency limits on all production Lambda functions. Size them to the maximum realistic load, not theoretically infinite. For event-driven functions (SQS, Kinesis), also set the batch size and maximum concurrency on the event source mapping to prevent runaway scaling.

Mistake 6: Ignoring CloudWatch Logs Costs

CloudWatch ingestion and retention charges increase with log volume. Review the service’s current regional pricing and measure verbose logging before estimating this part of the bill.

Log retention defaults to never expire. Old log data stored indefinitely adds storage costs.

Fix:

  • Set log retention to 30-90 days on all Lambda log groups
  • Use structured logging with a log level (INFO, DEBUG, ERROR) and suppress DEBUG logs in production
  • Sample debug logs at 1-5% for high-volume functions rather than logging every invocation
  • Review the CloudWatch line item in Cost Explorer monthly

Mistake 7: No Budget Alerts

AWS billing is billed in arrears. Without alerts, you discover problems at month-end. By then, the cost has already been incurred.

A misconfigured Lambda in an infinite retry loop, a DynamoDB table that gets unexpectedly hammered, or a forgotten development environment running at production scale — these are all problems that surface in the bill 20-30 days after they start, if you are not watching.

Fix: Create AWS Budgets for each major service category (Lambda, API Gateway, DynamoDB) and set alerts at 50%, 80%, and 100% of your expected monthly cost. Add a forecasted spend alert at 100% — this triggers before the period ends if spend is tracking above target. Route alerts to a Slack channel or an email address someone actually reads.


Start with the services contributing the most to your bill. Measure the effect of each configuration change under representative traffic before applying it broadly.

Discuss an AWS serverless cost review with LinkIT.