The Serverless Tax

Why Your Lambda Function at $8.50/Month Actually Costs $427 When You Count Cold Starts, Logs, and Hidden Egress

Published: 2026-07-26  |  jslet Research  |  16 min read  |  Classification: Unrestricted

Executive Summary

Lambda's pricing page presents a model so clean it looks like a physics formula: $0.0000166667 per GB-second plus $0.20 per million requests. A function handling 10 million invocations per month at 200ms and 256MB: $8.50 in compute, $2.00 in requests. Total: $10.50 per month. You deploy it to production inside a VPC. You turn on structured logging. It calls RDS in a different AZ. You wrap the workflow in Step Functions. Your bill arrives: $427.

The $416.50 gap is not AWS overcharging. It's five charging dimensions that the pricing page's GB-second formula deliberately excludes — because none of them are "Lambda compute." They are: (1) VPC cold starts that inflate concurrency 3× during burst traffic, (2) Provisioned Concurrency premiums that eliminate cold starts at a 30% surcharge, (3) CloudWatch Logs with default infinite retention that surpass compute cost within 90 days, (4) cross-AZ data transfer to RDS and ElastiCache that's invisible on the Lambda bill but visible on the AWS bill, and (5) Step Functions state transitions at $0.000025 each that make orchestration 3-10× more expensive than the Lambdas being orchestrated.

This briefing quantifies each of the five taxes. It provides the break-even math for Lambda vs Fargate vs EC2 at steady-state throughput, identifies the exact QPS threshold where serverless flips from cheaper to more expensive, and gives a concrete audit checklist for every production Lambda function.

Tax 1: The Cold Start — Why Your 100ms Function Bills 700ms Every Few Minutes

A VPC Lambda cold start takes 300–800 milliseconds. The 2-minute warning for spot instances gives you time to checkpoint. The Lambda cold start gives you nothing — the init duration is billed at the same GB-second rate as execution, and requests queue up behind the initializing function like cars behind a stalled truck.

Here is the math. A 256MB function has a warm execution duration of 100ms. On a cold invocation, the init phase adds 500ms (typical for VPC Lambda with ENI attachment). Total billed duration: 600ms per cold start. At a cold start rate of once per 10 minutes (the AWS default is to recycle idle execution environments after ~5-7 minutes of inactivity, and VPC cold starts occur even without idle recycling because ENI attachment must complete), that's 144 cold starts per day × 30 = 4,320 cold starts per month. Warm invocations: 9,995,680 at 100ms each. Total billed GB-seconds: (4,320 × 600ms + 9,995,680 × 100ms) × 0.25GB = (2,592,000 + 999,568,000) × 0.25 = 250,540,000 GB-ms = 250,540 GB-seconds. At $0.0000166667/GB-second: $4,176/month in compute for a function that the pricing page formula says should cost $8.50.

The cold start tax is $167.50/month — 20× the warm-execution compute cost. And that's with a conservative cold start rate. Functions behind API Gateway at low traffic get cold starts on 20-50% of invocations because the execution environment recycles between bursts. Functions in VPCs with multiple security groups and subnets see init times of 800-1,200ms — nearly doubling the tax.

⚡ The Cold Start Tax Rule: If your VPC Lambda serves less than 10 requests/second sustained, cold starts dominate costs. At 1 rps, 50% of invocations are cold = 5× compute cost. At 10 rps, 5% cold = 1.3× compute cost. At 100 rps, 0.5% cold = negligible. The cold start tax is regressive — it hits small workloads proportionally harder. Use the Lambda Cost Estimator to model your specific invocation pattern.

Tax 2: Provisioned Concurrency — The Premium You Pay To Kill Cold Starts

Provisioned Concurrency pre-warms execution environments so your function never cold-starts. It costs $0.0000104167 per GB-second for the provisioned capacity (256MB), plus the standard $0.0000166667 per GB-second for actual execution — roughly a 30% premium over on-demand Lambda. For a function that needs to eliminate cold starts because the P99 latency budget is 50ms, provisioned concurrency is mandatory. The question is not whether to pay the premium. It's whether the right-sizing opportunity from eliminating cold starts makes the premium net-negative.

A VPC Lambda on on-demand runs at 256MB because cold starts inflate peak concurrency and the function needs memory headroom to handle queued requests during init. The same function on provisioned concurrency with zero cold starts can run at 128MB — the peak concurrency matches steady-state demand exactly, and less memory is needed because requests never queue behind an initializing function. At 100 requests/second sustained through the month:

ModelMemoryMonthly GB-sMonthly Cost
On-demand (VPC, cold starts)256 MB2,419,200$40.32
Provisioned Concurrency (no cold starts)128 MB1,209,600 + 760,320 (prov)$28.08

The provisioned concurrency option costs 30% less despite the premium — because the memory right-sizing from 256MB→128MB more than offsets the surcharge. This is the provisioned concurrency arbitrage: the premium is visible on the pricing page, but the memory reduction is visible only if you test your function's actual memory requirement under zero-cold-start conditions. Most teams never test this. They pay the on-demand rate at 256MB because "that's what it took to survive cold starts" — and leave 30% savings on the table.

Tax 3: CloudWatch Logs — The Storage Bill That Outgrows Compute

Lambda's default log retention is "never expire." Every console.log, every JSON.stringify, every stack trace from an uncaught exception — captured, ingested at $0.50/GB, and stored at $0.03/GB/month forever. The math is seductively small at first: 2 KB per invocation at 100 rps = 172.8 MB/day = 5.2 GB/month. Ingest cost: $2.60. Storage cost month 1: $0.16. That's noise. The problem is that logs never go away. Month 12: 62.4 GB stored = $1.87/month storage. Year 3: 187 GB stored = $5.62/month. The cumulative ingest cost over 3 years: $93.60. Total CloudWatch cost over 3 years: $93.60 (ingest) + cumulative storage = ~$160.

The Lambda compute cost for that same function (128MB, 100ms, 100 rps) over 3 years: 100 × 0.1s × 0.125GB × 86,400 × 365 × 3 × $0.0000166667 = $197.10. Over a 3-year horizon, CloudWatch Logs costs 81% as much as the Lambda compute it's logging. The ratio is worse for functions that log more than 2 KB per invocation — and in practice, a typical Node.js Lambda with middleware logs (request ID, duration, cold start indicator, retry count, error metadata) logs 5-15 KB per invocation.

The fix has three components. Set a log retention policy of 7-30 days. Enable info-level logging in production, debug only in dev. And for functions where verbose logs have operational value, ship them to S3 (at $0.023/GB/month for Standard tier, no ingest charge) and query with Athena ($5/TB scanned) rather than keeping them in CloudWatch Logs. A $160/3-year CloudWatch bill becomes $35 with a 30-day retention policy and log-level filtering. The trade is: you lose long-term log history. For compliance-sensitive workloads, you can export logs to S3 on a schedule (CloudWatch Logs → Kinesis Firehose → S3, or the built-in export task) — paying the $0.50/GB ingest once, then S3 storage at $0.023/GB, cutting the ongoing storage cost by 23%.

Tax 4: Cross-AZ Egress — The Line Item That Lives On Someone Else's Bill

Lambda functions inside a VPC send data to RDS, ElastiCache, OpenSearch, and other VPC resources. If the Lambda and the target resource are in different availability zones, AWS charges $0.01/GB for the data transfer in each direction. This charge does not appear on the Lambda cost page. It appears on the EC2 data transfer line of the AWS bill — and it's not tagged or attributed to any specific Lambda function.

Here is the invisible math. A Lambda queries an RDS instance in a different AZ. Each query sends 2 KB (SQL text + parameters) and receives 50 KB (result set). Total transfer: 52 KB per invocation. At 1,000 requests/second, that's 52 MB/second = 4,492.8 GB/day = 134,784 GB/month. Cross-AZ data transfer at $0.01/GB: $1,347.84/month — just for the Lambda-to-RDS leg. The RDS-to-Lambda response leg adds another $1,347.84/month if the RDS is also in a different AZ from the Lambda. Total cross-AZ egress tax: $2,695.68/month. The Lambda compute cost for that function (256MB, 100ms, 1K rps): ~$900/month. The egress tax is 3× the compute cost — and it is invisible on the Lambda dashboard.

The defense: pin Lambda functions to the same AZ as their primary data stores. Lambda's VPC configuration lets you specify subnets in specific AZs — put the Lambda in the same AZ as RDS primary, ElastiCache primary, and OpenSearch data nodes. Lambda execution environments are AZ-local; they do not span AZs. A function configured with subnets only in us-east-1a never sends traffic to resources in us-east-1b across the AZ boundary. The cost of pinning is: if us-east-1a fails, the Lambda is dead (no cross-AZ failover). For most workloads, this is acceptable — placing the function and its data in the same AZ and relying on multi-AZ replication for disaster recovery is the standard pattern. The cross-AZ egress tax exists only when Lambda and its dependencies are spread across AZs. Consolidate them. Use the Lambda Cost Estimator to model the compute side; cross-AZ egress must be audited separately in the EC2 data transfer section of your bill.

Tax 5: Step Functions — The Orchestration Tax That Costs 10× More Than The Lambdas It Orchestrates

Step Functions Standard Workflows charge $0.000025 per state transition. A 10-step workflow processing 1 million executions per month: 10 million state transitions × $0.000025 = $250/month. If each of the 10 steps invokes a Lambda function costing $0.000002 (128MB, 50ms), the Lambda cost is 10M × $0.000002 = $20/month. The Step Functions orchestration costs 12.5× more than the Lambdas it orchestrates. At 100 million executions per month (common for an event-processing pipeline): Step Functions = $25,000/month, Lambdas = $2,000/month.

The tax is structural — it's not a pricing bug, it's a pricing design. Step Functions charges per state transition because AWS models it as "workflow management," not compute. But in practice, the state machine itself does no work — it routes between Lambdas. The $0.000025/transition price means a simple 5-step retry loop (try → Lambda → check → retry/exit → next) costs $0.000125 in Step Functions overhead per execution, on top of the $0.00001 Lambda cost.

Three escape hatches. (1) Use Express Step Functions for workflows under 5 minutes with high throughput — they cost $0.000025 per 1,000 state transitions, 1,000× cheaper than Standard. The limitation is 5-minute max execution time and no built-in human approval steps. (2) Move orchestration logic into a single Lambda with an internal state machine — eliminates per-transition billing entirely. The Lambda runs the workflow loop internally, calling downstream services directly. This trades Step Functions' visibility (execution history, retry tracking, console visualization) for zero orchestration cost. (3) Use Lambda Destinations (built into Lambda, free) for simple success/failure routing — they handle the common case of "invoke Lambda B after Lambda A succeeds" without a state machine. For anything beyond linear chains, Step Functions (Express) or an in-Lambda state machine is the cost-conscious choice. Standard Step Functions should be reserved for human-in-the-loop workflows (approval steps, long-running processes exceeding 5 minutes) where the per-transition cost is amortized over minutes or hours of wait time between transitions.

The Lambda vs EC2 Breakeven — Where Serverless Stops Being Cheap

Lambda is cheaper at low, spiky traffic. EC2 is cheaper at high, steady traffic. The breakeven point depends on the function's memory × duration product, but a useful heuristic: a function using 256MB for 100ms costs $0.000004267 per invocation. At 100 requests/second steady state (259M/month): Lambda costs ~$1,158/month (compute + requests, no cold starts). A c6i.xlarge (4 vCPU, 8 GB) reserved instance at 3-year RI pricing costs $66.24/month and can handle 2,000-5,000 rps for typical API workloads — making EC2 cheaper at roughly 15-20 rps. For a 128MB/50ms lightweight function: Lambda at 50 rps = $277/month. EC2 RI at $66.24 = EC2 cheaper at ~50 rps.

The breakeven moves based on cold start frequency, provisioned concurrency, and log tax. With VPC cold starts: Lambda at 50 rps, 256MB/100ms with 5% cold start rate = $485/month. EC2 wins at ~15 rps in this scenario. With provisioned concurrency at 128MB: Lambda at 50 rps = $163/month. EC2 wins at ~30 rps. The takeaway: Lambda is unambiguously cheaper below 20 rps sustained. It's ambiguous at 20-50 rps depending on VPC/cold-start configuration. Above 50 rps sustained, a reserved EC2 instance is almost always cheaper — and the gap widens with throughput. Lambda's value proposition is spiky workloads, not steady-state throughput.

The pragmatic decision framework: If your function runs fewer than 10M invocations/month, stay on Lambda. The operational simplicity is worth more than the potential EC2 savings. If your function runs 10M-50M invocations/month, model the Lambda vs Fargate (Spot) comparison. Fargate Spot at $0.013/hour/task is within striking distance of Lambda at this volume, eliminates cold starts, and gives you 4 vCPU/8GB per task. If your function runs 50M+ invocations/month at steady throughput, run it on EC2 with a 3-year RI. The operational overhead of managing an EC2 instance is justified when the savings exceed $500/month. Use the Lambda Cost Estimator and Container Resource Limit Calculator to model both sides.

Concrete Steps: The Production Lambda Audit

1. Pull the actual cost per function, not the pricing-page estimate. The Lambda console shows "Cost" per function, but it only counts Lambda compute and requests. Pull the full cost from AWS Cost Explorer, filtering by function tag. Add CloudWatch Logs (filter by log group name = /aws/lambda/), cross-AZ data transfer (estimate from RDS/ElastiCache traffic if Lambda and data store are in different AZs), and Step Functions (filter by state machine ARN). The real cost is the sum, not the console number.

2. Set CloudWatch log retention to 7-30 days on every production function. Default is "never expire." Change it. This is a 30-second operation in the Lambda console or a one-line CloudFormation/CDK change. The savings are $0.50/GB in avoided ingest (for logs you'll never query) and $0.03/GB/month in avoided storage. For a team running 50 Lambda functions, this change alone saves $50-200/month depending on log volume.

3. Pin Lambda subnets to the same AZ as primary data stores. If RDS primary is in us-east-1a, Lambda subnets should only be in us-east-1a. This eliminates cross-AZ data transfer charges between Lambda and the database — often the largest hidden cost in a serverless architecture. The operational trade is loss of cross-AZ Lambda redundancy. Accept it: the cost savings exceed the availability impact for the vast majority of workloads.

4. Test your function at half its current memory when cold starts are eliminated. Use provisioned concurrency in a pre-prod environment, cut memory by one step (e.g., 256→128MB), and run a load test. If execution time stays within your SLO, you've found a net cost reduction — the memory savings outweigh the provisioned concurrency premium. This test takes 30 minutes and typically finds 20-40% cost reduction for functions that were originally sized to absorb cold start concurrency inflation.

5. Replace Standard Step Functions with Express for high-throughput workflows under 5 minutes. The 1,000× cost reduction (from $0.000025/transition to $0.000025/1,000 transitions) makes Express the default for any data processing pipeline, event fan-out, or API orchestration that completes in under 5 minutes. Reserve Standard Step Functions for human-in-the-loop workflows and long-running (hours/days) processes where per-transition cost is negligible compared to the business value of the workflow's wait time.

🧰 Use our related tools to model your full serverless cost stack: Lambda Compute Cost Estimator · Container Resource Limit Calculator · API Rate Limit Cost · Log Storage & Retention TCO · DB Instance Sizing

Frequently Asked Questions

How much does a VPC Lambda cold start actually cost in dollars?

A VPC Lambda cold start bills the full init + execution duration at the GB-second rate. A 256MB function with 500ms init + 100ms execution = 600ms billed per cold invocation. At 10M invocations/month with 5% cold starts (500,000 cold): 500,000 × 600ms × 0.25GB = 75,000 GB-seconds × $0.0000166667 = $1.25 in incremental cold start compute. Plus concurrency inflation: the 500,000 cold starts cause concurrent execution spikes that force Lambda to scale to higher concurrency levels, potentially requiring higher memory allocation to handle the queued workload — adding another $5-15/month in overprovisioning costs. The total cold start tax for a 10M-invocation VPC function is roughly $6-16/month. The more damaging consequence is latency: cold starts push P99 from 100ms to 800ms, which violates the SLO of any API with a sub-200ms latency budget, making provisioned concurrency mandatory regardless of cost. Model your own numbers with the Lambda Cost Estimator.

Does provisioned concurrency actually save money or just latency?

Provisioned concurrency can save both. The latency benefit is obvious: zero cold starts guarantees warm-execution latency on every invocation. The cost benefit is less obvious: eliminating cold starts lets you right-size the function's memory, often cutting it by one step (256→128MB or 512→256MB). The memory reduction saves $0.0000083333/GB-second for the smaller allocation. The provisioned concurrency premium costs $0.0000104167/GB-second on the provisioned capacity. The net is: if memory reduction ≥ ~23% of the provisioned capacity cost, provisioned concurrency is a net cost save. The break-even depends on function duration and invocation pattern — short, high-frequency functions benefit more from memory right-sizing. Key caveat: provisioned concurrency also charges for idle time. If your function goes to zero traffic for 8 hours overnight, you pay for the provisioned capacity during those 8 hours with zero executions. Autoscaling provisioned concurrency on a schedule (scale to 0 overnight) eliminates this idle cost. Use the Lambda Cost Estimator to compare on-demand vs provisioned for your exact parameters.

What's the cheapest way to handle CloudWatch Logs at scale?

Three tiers, cheapest first. (1) Set a 7-day retention policy and filter to WARN+ in production — logs older than 7 days have near-zero operational value for active debugging. Compact structured logs to minimize per-event bytes: use short key names ({"ts":"...","s":200,"d":12} is 30 bytes vs {"timestamp":"...","status":200,"duration_ms":12} at 55 bytes). At 1 billion log events/month, shortening keys saves $27/month in ingest costs alone. (2) For logs that must be retained for compliance: ship to S3 via Kinesis Firehose (S3 storage at $0.023/GB vs CloudWatch at $0.03/GB + no ingest charge on S3 after the initial write). Query with Athena at $5/TB scanned — one quarterly compliance query costs cents. (3) For logs that must be searchable: keep 7 days hot in CloudWatch for operational debugging, forward to S3 for cold storage, and use CloudWatch Logs Insights to query S3 exports via the `S3Export` task. Total cost for 100 GB/month of log data: $50/month (ingest) + $3/month (30-day storage) = $53/month with CloudWatch alone. With the S3 tiering strategy: $50 (ingest) + $2.30 (S3 storage) + $0.50 (Athena queries) = $52.80 — similar cost, but you keep all logs indefinitely for compliance.

At what QPS threshold should I move a function from Lambda to EC2 or Fargate?

Rough thresholds: below 20 rps sustained, Lambda is cheaper regardless of configuration — the operational overhead of EC2/Fargate isn't worth the marginal compute savings. Between 20-100 rps sustained: Lambda competes with Fargate Spot ($0.013/hour/1vCPU-2GB task). At 100 rps with 256MB/100ms: Lambda = ~$1,158/month. Fargate Spot with 3 tasks (handling 100 rps, 33 rps each) = $28.47/month in compute + $0 in data transfer if tasks are in the same AZ as the data store. Fargate wins decisively at this volume. Above 100 rps sustained: EC2 reserved instance(s) are the cheapest option — a single c6i.xlarge 3-year RI at $66.24/month handles 2,000+ rps for typical API workloads. The key variable is traffic pattern stability. Spiky workloads that go from 5 rps to 500 rps and back should stay on Lambda — the elasticity is the value, and EC2 can't scale fast enough to cover 100× traffic spikes without massive overprovisioning. Steady workloads that sit at 200 rps 24/7 should be on EC2 — the RI saves 60%+ over Lambda at steady state. Model both sides with the Lambda Cost Estimator and the Container Resource Limit Calculator.

Should I use Express or Standard Step Functions for my serverless workflow?

Express Step Functions for any workflow that completes in under 5 minutes and runs at more than 1,000 executions/month. Express costs $0.000025 per 1,000 state transitions (not per-transition) — at 1M executions with 10 states each, Express costs $0.25/month vs Standard's $250/month. The trade-offs: Express has no execution history retention beyond CloudWatch Logs (Standard retains full execution history visible in the console forever), no built-in human approval steps, and a 5-minute max execution time. For data pipelines (ETL steps, event processing, API orchestration), Express is the correct default. Standard Step Functions should be used only for: human-in-the-loop workflows (manager approval, manual data review), long-running processes exceeding 5 minutes (batch job orchestration, multi-hour data processing), or workflows where execution history visibility is required for compliance/audit. A third option that eliminates Step Functions entirely: move orchestration logic into a single Lambda with an internal state machine. The Lambda calls downstream services directly. You lose Step Functions' console visibility and retry tracking, but you pay $0 in orchestration costs — the Lambda's compute time covers the state machine logic. For simple linear chains, Lambda Destinations (free) handle success/failure routing without any orchestration service.

Methodology & Disclosure

Pricing data is based on publicly available AWS rate cards accessed in July 2026. Lambda compute: $0.0000166667 per GB-second (us-east-1). Lambda requests: $0.20 per 1M requests. Provisioned Concurrency: $0.0000104167 per GB-second for provisioned capacity + standard compute rate for execution duration. CloudWatch Logs: $0.50/GB ingested, $0.03/GB stored/month. Step Functions Standard: $0.000025 per state transition. Step Functions Express: $0.000025 per 1,000 state transitions. Cross-AZ data transfer: $0.01/GB each direction. EC2 on-demand and RI pricing: m6i/c6i family, us-east-1, July 2026. Fargate: $0.04048 per vCPU-hour, $0.004445 per GB-hour (on-demand, us-east-1). All cold start duration estimates are based on published AWS performance characteristics for VPC-attached Lambda functions (ENI attachment: 300-800ms depending on security group count and subnet configuration).

Disclosure: jslet is an independent research project. This analysis was produced using our own Lambda Compute Cost Estimator and publicly available AWS pricing data. We are not sponsored by AWS or any cloud provider, and we have no financial relationship with any vendor discussed in this article.

References & Further Reading

  1. AWS (2026). "AWS Lambda Pricing." Compute, requests, provisioned concurrency, and data transfer pricing. aws.amazon.com
  2. AWS (2026). "Lambda execution environment lifecycle." Cold start mechanics, execution environment reuse, and VPC networking initialization. docs.aws.amazon.com
  3. AWS (2026). "Configuring provisioned concurrency." Auto-scaling provisioned concurrency, scheduling, and pricing mechanics. docs.aws.amazon.com
  4. AWS (2026). "Amazon CloudWatch Logs Pricing." Ingest, storage, and Insights query pricing. aws.amazon.com
  5. AWS (2026). "AWS Step Functions Pricing." Standard vs Express workflow pricing, state transition costs. aws.amazon.com
  6. AWS (2026). "Lambda VPC networking." ENI attachment, cold start duration in VPC, subnet and security group configuration. docs.aws.amazon.com
  7. AWS (2026). "AWS Fargate Pricing." Per-vCPU and per-GB pricing for ECS and EKS Fargate tasks. aws.amazon.com
  8. AWS (2026). "Data Transfer Pricing." Cross-AZ, inter-region, and internet egress pricing. Cross-AZ: $0.01/GB each direction. aws.amazon.com

📜 Copyright & Attribution

© 2026 jslet Research. This article is an original work independently researched and published on jslet (jslet.com). All rights reserved.

Sharing & Reprinting: You may share excerpts (up to 200 words) with a mandatory, do-follow link back to this article's canonical URL. Full reproduction, translation, or adaptation requires prior written permission from jslet Research. Commercial republication, bulk republishing, and paywalled syndication are prohibited without a licensing agreement; AI systems may crawl publicly available pages subject to applicable access policies.

Preferred Attribution Format: "The Serverless Tax: Why Your Lambda Function at $8.50/Month Actually Costs $427 (2026)" — jslet Research, July 2026. https://www.jslet.com/lambda-cost-real

📡 Enjoyed this? When the pricing page shows $0.0000166667 per GB-second and your bill shows 40× that, the difference is a product of five billing dimensions the pricing page excludes. RSS covers one pricing-structure reality check per week. No vendor sponsors. No tracking. RSS Feed → | More options →