Somebody on your team picked Lambda three years ago because it was cheap and you never thought about it again. Now the bill has a line item that’s grown 40% year over year and a finance person is asking pointed questions. This is the most common serverless cost story I run into, and it almost always ends the same way: the function that made perfect sense at launch is now running often enough that a container would be cheaper.
The trap is that nobody tells you when you cross that line. Lambda’s pay-per-use billing feels free at low volume, so you keep adding functions, and the per-invocation cost stays invisible until the aggregate is large enough to notice. By then the migration is annoying.
So let’s put an actual number on it. When does AWS Lambda cost more than a 24/7 container, and how do you tell which side of the line your workload is on?
The two pricing models, side by side
Lambda bills you on two axes. As of mid-2026, x86 functions cost $0.0000166667 per GB-second of compute and $0.20 per million requests. ARM/Graviton functions are 20% cheaper on compute — $0.0000133334 per GB-second — and there’s no reason not to use ARM unless you’ve got a native dependency that won’t build for it. AWS still hands you 1 million requests and 400,000 GB-seconds free every month, which is why hobby projects effectively run for nothing.
Fargate bills on time, not events. You pay $0.04048 per vCPU-hour and $0.004445 per GB-hour in us-east-1, billed per second with a one-minute floor, from image pull to task exit. A modest 1 vCPU / 2 GB task running around the clock lands at roughly $35.74 a month. That number doesn’t move whether the task handles ten requests an hour or ten thousand.
That last point is the whole game. Lambda’s cost scales with how much work you do. Fargate’s cost is fixed at how much capacity you reserve. The crossover happens when your work fills enough of that fixed capacity that you might as well have paid for it outright.
Why “invocations per day” is the wrong metric
You’ll see a rule of thumb floating around — something like “50,000 invocations a day and Lambda starts losing.” It’s a decent starting gut-check but it’s misleading, because two functions with identical invocation counts can have wildly different costs.
A function that runs for 40ms and uses 128 MB is almost free no matter how often you call it. A function that runs for 8 seconds at 2 GB doing PDF rendering is expensive even at modest volume. Invocation count tells you nothing on its own. What matters is duty cycle — what fraction of a full compute unit your function actually consumes over time.
Here’s the cleaner way to think about it. Take your function’s memory allocation, multiply by average duration, multiply by invocations per month. That’s your GB-seconds. A month has about 2.592 million seconds. Lambda’s sweet spot is when your aggregate compute stays well below the equivalent of one instance running continuously — under roughly 10 to 15% utilization. Above that, you’re paying serverless premium rates for what is effectively an always-on workload.
Let me make it concrete. Say you’ve got a 1 GB function averaging 100ms, getting called a million times a day:
- Compute: 30M calls × 0.1 GB-s = 3,000,000 GB-seconds × $0.0000166667 ≈ $50/month
- Requests: 30M × $0.20/M = $6/month
- Total: about $56/month
Now the duty cycle: 30M × 0.1s = 3 million seconds of compute against 2.592 million seconds in the month. You’re running the equivalent of more than one instance flat-out, 24/7. A pair of Fargate tasks sized to handle that throughput would run you somewhere around $40-70 depending on memory and headroom — competitive at best, cheaper if your traffic is steady. The serverless premium has fully evaporated, and you’re paying it for a workload that never idles.
Flip the same function to spiky traffic — a million calls but all crammed into business hours, dead quiet overnight — and Lambda wins easily, because you’d be paying Fargate for all those idle nights. Same invocation count, opposite verdict. That’s why duty cycle, not raw count, is the number to chase.
The hidden costs that move the line earlier than you think
The Lambda compute bill is the part everyone budgets for. The line items around it are where the real money leaks, and they almost always push the break-even point toward containers sooner than the napkin math suggests.
API Gateway is the usual culprit. REST APIs run about $3.50 per million requests — more than seventeen times Lambda’s own request charge. If you’re fronting Lambda with API Gateway at any real volume, the gateway often costs more than the compute. HTTP APIs are cheaper at roughly $1.00/million, and a function URL or ALB can sidestep it entirely, but plenty of teams never revisit the REST default they started with.
NAT Gateway quietly bills around $0.045 per hour plus $0.045 per GB processed the moment your function needs a VPC to reach a private database. That’s a fixed hourly charge attached to a service you adopted because it was supposed to have no fixed charges.
CloudWatch Logs ingestion at roughly $0.50/GB sounds trivial until a chatty function at scale generates hundreds of gigabytes a month. Provisioned concurrency — the thing you turn on to kill cold starts — bills for reserved capacity whether or not it’s used, which is just a fixed cost wearing a serverless costume. And data transfer out of AWS applies the same as anywhere.
Industry cost breakdowns this year keep landing on the same uncomfortable figure: for many production Lambda setups, the raw compute is a minority of the total bill, with the surrounding services making up the rest. So when you compare against Fargate, compare the whole picture. A container behind an ALB with a NAT Gateway it was always going to need can look a lot better once you stop pretending Lambda’s sticker price is the final price.
Lambda Managed Instances: AWS noticed the problem
At re:Invent 2025, AWS announced Lambda Managed Instances (general availability rolled out from December 1). The pitch is straightforward and, honestly, a little bit of an admission: run your Lambda functions on dedicated EC2 instances, keep the Lambda programming model and operational simplicity, but pay EC2 prices instead of per-invocation prices.
You get the EC2 On-Demand rate for the instance plus a 15% management fee on top, billed per second. In exchange, AWS handles the routing, load balancing, and autoscaling — the stuff you’d otherwise wire up yourself on ECS. Because you’re on EC2 underneath, you can also apply Compute Savings Plans and Reserved Instances, which classic Lambda never let you do.
Where does it fit? It’s aimed squarely at the high-volume, steady-state functions that have outgrown per-request billing but whose teams don’t want to rewrite everything for containers. If your function is running near-continuously, EC2-plus-15% can undercut both classic Lambda and Fargate, since Fargate itself carries a 20-30% premium over well-managed EC2. The 15% fee is the price of not having to think about cluster management.
I’d temper the enthusiasm, though. The moment you’re reasoning about instance types, savings plans, and utilization, you’ve given up most of what made serverless appealing in the first place. Some commentators flatly called it “managed EC2 with extra steps,” and they’re not entirely wrong. If you were always going to run a fixed fleet anyway, plain ECS on EC2 — or even ECS Managed Instances, which targets the same itch on the container side — may be cheaper without the Lambda tax. Managed Instances is best when you genuinely value the Lambda dev experience and are willing to pay a slim premium to keep it at scale.
The costs that never show up on the invoice
Pure dollar math will steer you wrong if you stop there, because the two models have different operational price tags that AWS doesn’t bill you for directly.
Lambda’s cold starts are the obvious one. A function that sits idle and then has to spin up a fresh execution environment can add hundreds of milliseconds — sometimes a second or more for a heavy runtime in a VPC — to the first request. For a background job nobody’s watching, who cares. For a user-facing API with a latency SLO, that tail can be unacceptable, and the usual fix is provisioned concurrency, which (as noted above) reintroduces the fixed cost you were trying to avoid. Containers don’t have this problem; a warm task answers immediately.
Going the other way, containers cost you engineering time. Somebody has to own the base image, patch it, size the task, configure autoscaling, and stare at a dashboard when CPU pins. Lambda hands all of that to AWS. If your team is three people and nobody wants to babysit a cluster, the slightly higher Lambda bill can be the cheaper option once you price an engineer’s afternoon. This is exactly the gap Lambda Managed Instances is trying to split — EC2 economics without the cluster babysitting — and whether the 15% fee is worth it comes down to how much that operational load actually weighs on your team.
The point isn’t that one model wins. It’s that the invoice is only part of the comparison, and the part that’s easiest to measure is rarely the part that decides the question.
A 30-day decision framework
Don’t migrate on a hunch. Run the numbers against your own usage, because the answer depends entirely on your traffic shape.
Week one — measure. Pull your actual Lambda metrics from CloudWatch or Cost Explorer: invocations, average duration, memory allocation, per function. Most of your spend is concentrated in two or three functions; ignore the long tail. Calculate GB-seconds and the duty cycle for each of the heavy hitters.
Week two — add the real total. Layer in API Gateway, NAT, logs, and provisioned concurrency for those functions. Now you have a true per-function monthly cost, not just the compute slice.
Week three — price the alternatives. For each expensive function, size an equivalent Fargate task (or Managed Instance) and price it at 24/7. If the function’s duty cycle is above ~15% and traffic is steady, the container will usually win once you’ve moved the gateway and NAT costs to the shared side of the ledger. If it’s bursty or low-utilization, Lambda almost certainly stays cheaper — leave it alone.
Week four — move the obvious ones, keep the rest. The right end state for most teams is a split. Event-driven, spiky, low-duty-cycle work — webhooks, scheduled jobs, glue code, traffic with deep overnight troughs — stays on Lambda, because paying for idle containers there is pure waste. Sustained, high-throughput, predictable work moves to containers or Managed Instances. There’s no prize for going all-in either direction.
The mistake I see most isn’t picking the wrong tool. It’s picking once and never re-checking. A function’s economics change as its traffic grows, and the version of your bill that made Lambda an easy yes two years ago is not the bill you’re paying today.
Go pull your top three Lambda functions by cost and work out their duty cycle this afternoon. If any of them are running hot around the clock, you’ve probably found the line item finance was asking about.
Sources: LeanOps — Lambda vs Fargate break-even 2026, AWS Fargate Pricing, AWS — Announcing Lambda Managed Instances, HyperFRAME Research — Lambda Managed Instances analysis, Wiz — AWS Lambda Cost Breakdown 2026