Serverless Explained: What It Is and When It Costs More
Serverless is a billing model wearing an architecture costume. Once you do the arithmetic on published AWS prices, a Lambda function crosses over and becomes the expensive option at around 7.5 million requests a month. The number that decides it isn't your scale. It's your duty cycle.

Key takeaways
- Serverless is a billing model, not an architecture. AWS Lambda charges $0.20 per million requests plus $0.0000166667 per GB-second in US East (N. Virginia), so an idle function costs exactly nothing and a busy one is metered in milliseconds.
- A 512 MB Lambda function running 120 ms per request costs $0.0000012 per request. An always-on AWS Fargate task at 0.25 vCPU and 0.5 GB costs about $9.01 a month. The two lines cross at roughly 7.5 million requests a month, or about 2.9 requests per second.
- At that crossover point the equivalent always-on container is only about 40% busy, which means duty cycle, not scale, is the variable that decides whether serverless is cheap.
- Per unit of CPU time, Lambda costs about 2.1 times what Fargate costs: a 1,769 MB Lambda (one vCPU equivalent) runs $0.0000288 per second against $0.0000137 for a 1 vCPU, 2 GB Fargate task.
- AWS states cold starts occur in under 1% of invocations and last from under 100 ms to over 1 second, and the largest contributor is your own initialization code, not the platform.
Serverless is a way of paying for compute. That is the whole thing. You hand a cloud provider a zip file or a container image, tell it how much memory the code needs, and it runs that code inside a managed execution environment it creates, freezes, thaws and eventually throws away without telling you.[3] There is no machine you log into, no kernel you patch, and no capacity you reserve. When nothing calls your code, you owe nothing. When something does, AWS meters it in milliseconds.
The word makes it sound like an architecture. It isn't. It's a billing model with a runtime attached, and the second you treat it as a billing question the whole decision gets easy. AWS Lambda charges $0.20 per million requests and $0.0000166667 per GB-second of x86 compute in US East (N. Virginia).[1] Those two numbers, plus your traffic shape, tell you everything.
So let's actually do the arithmetic, because almost nobody does. I went looking for the point where a function stops being the cheap option and starts being the expensive one, and the answer surprised me: it isn't about scale at all.
What you actually hand over
Four things change when code moves into a function. The provider owns the operating system and the runtime patching. The environment scales to zero, so an endpoint nobody hits costs nothing. Billing is per invocation and per unit of duration rather than per hour of a rented box. And you lose the machine as a place to keep state, because AWS freezes the environment after each invocation and terminates it every few hours anyway, even for functions that are invoked continuously.[3]
That last one is the part people underrate. Your process is not long-lived, so anything you were relying on a long-lived process for stops working the way you expect. In-memory session state. A warm connection pool. A background worker that finishes after the response goes out. All of it becomes somebody else's problem, and the somebody is you.
The trade
What the platform takes over, and what stays yours
You provide
- Code artifactA .zip under 250 MB unzipped, or a container image up to 10 GB
- A memory setting128 MB to 10,240 MB. CPU scales with it
- An event sourceHTTP gateway, queue, schedule, object upload
Managed execution environment
AWS creates it, runs your init code, invokes the handler, freezes it, reuses it, then discards it
You stop paying for
- Idle capacityZero requests costs zero dollars
- OS patchingNo kernel, no base image, no fleet to roll
- Capacity planningScaling is the platform default, not a project
Lambda quotas and execution environment behavior as documented by AWS.
Takeaway
You are trading capacity planning for state homelessness. Everything a long-lived process gave you for free, from a warm connection pool to an in-memory cache, now needs an explicit answer.
The cost crossover, worked out
Take a boring API endpoint. It reads a row, does a little work, returns JSON. Call it 512 MB of memory and 120 ms of billed duration, which is a realistic shape for a warm handler doing one database round trip. Now price it both ways.
# AWS Lambda, x86, first duration tier
REQUEST_PRICE = 0.20 / 1_000_000 # $ per request
GB_SECOND = 0.0000166667 # $ per GB-second
memory_gb, duration_s = 0.5, 0.120
per_request = memory_gb * duration_s * GB_SECOND + REQUEST_PRICE
# -> $0.0000012 per request
# AWS Fargate, Linux/x86, always on
VCPU_SECOND = 0.000011244 # $ per vCPU-second
MEM_SECOND = 0.000001235 # $ per GB-second
vcpu, mem_gb = 0.25, 0.5
seconds_per_month = 730 * 3600 # 2,628,000
monthly = (vcpu * VCPU_SECOND + mem_gb * MEM_SECOND) * seconds_per_month
# -> $9.01 per month, whether anyone calls it or not
crossover = monthly / per_request
# -> 7,508,000 requests per month, about 2.9 per secondSeven and a half million requests a month, or 7.5 million if you prefer it as a number you can search for. That is the line. Under it, the function is cheaper, and at low volume it is dramatically cheaper: two million requests costs $2.40 against $9.01 for the container, and the first million requests plus 400,000 GB-seconds are free anyway.[1] Over the line, the function loses, and it keeps losing faster the more traffic you send, because its bill is a straight line through the origin and the container's is flat.
2 million requests a month
30 million requests a month
- AWS Lambda, 512 MB / 120 ms$2.40$36.00
- AWS Fargate, 0.25 vCPU / 0.5 GB$9.01$9.01
Takeaway
The serverless bill is a line through the origin. The always-on bill is flat. Two lines like that cross exactly once, and where they cross is a property of your traffic, not of your engineering.
Duty cycle is the variable, not scale
Here's the part I find genuinely interesting. Look at what the container is doing at the moment the two lines cross.
At 1,769 MB a Lambda function gets the equivalent of one vCPU.[2] So a 512 MB function is running on roughly 0.29 of a vCPU, and 120 ms of it consumes about 0.035 vCPU-seconds of work. A 0.25 vCPU Fargate task delivers 0.25 vCPU-seconds every second, so it can absorb about 7.2 of those requests per second before it saturates. The crossover sits at 2.9 requests per second. That is 40% utilization.
Run the same comparison at matched shapes and you get the same answer from the other direction. A 1,769 MB Lambda costs $0.0000288 per second of one-vCPU compute. A 1 vCPU, 2 GB Fargate task costs $0.0000137 per second.[1,4] Lambda is about 2.1 times the price per unit of CPU time, which means it wins right up until the box you would otherwise rent is busy more than about half the time.
“Serverless doesn't get expensive because you got big. It gets expensive because you got steady.”
This reframes the whole argument. “Will we outgrow serverless?” is the wrong question, because a service handling a hundred million requests a month in four sharp daily spikes can still be firmly on the cheap side of the line, while a background job that quietly chews CPU at a constant rate is on the expensive side at a fraction of that volume. Spiky and low duty cycle wins. Steady and high duty cycle loses. Scale is almost irrelevant except insofar as it correlates with duty cycle, and in real systems it correlates a lot less than people assume.
Receipt
The constraints that aren't on the landing page
Cost is the argument people have. These are the things that actually break projects.
Cold starts, and what really causes them. When no warm environment exists, AWS downloads your code, starts an environment and runs your initialization code before the handler executes. AWS says this happens in under 1% of invocations and lasts from under 100 ms to over 1 second.[3] The important detail is whose fault it is: AWS states plainly that the largest contributor to pre-execution latency is the initialization code you wrote, driven by package size, imported libraries and connection setup.[3] A fat SDK import in the global scope is a self-inflicted cold start. The Init phase is also capped at 10 seconds for on-demand functions.[3]
Fifteen minutes, and 6 megabytes. A function times out at 900 seconds, period.[2] Synchronous requests and responses cap at 6 MB each, asynchronous at 1 MB.[2] Video transcoding, big report generation and anything that streams a large file need a different execution model or a chunking strategy, and the chunking strategy is real work that a long-running process would never have needed.
The connection pool problem. This is the one that bites hardest. The default quota is 1,000 concurrent executions per region,[2] and each one is a separate environment that will happily open its own database connection. Your pooling library, which assumes one process serving many requests, now has a pool of one inside each of a thousand processes. AWS recommends Amazon RDS Proxy for exactly this, describing it as a service that “manages a pool of shared database connections which enables your function to reach high concurrency levels without exhausting database connections.”[5] That proxy is billed hourly, which is quietly funny: the fix for your always-on cost being zero is to add an always-on component. This is also the moment to get serious about caching in front of the database, because a cache hit is a connection you never opened.
Heads up
Lock-in through the event model, not the runtime. People worry about the wrong lock-in. Your handler is ordinary Python or Node and it ports in an afternoon. What doesn't port is everything around it: the event shapes, the IAM policies, the queue semantics, the retry and dead-letter behavior, the fact that your application's control flow now lives in a cloud console rather than in your code. That is the same coupling problem you get when splitting a monolith into services, except the wiring belongs to a vendor.
The observability tax. You cannot attach a profiler to a process that no longer exists. You get logs, metrics and traces, you pay per gigabyte ingested, and the volume is proportional to invocations rather than to machines. A container on a box you control gives you the same telemetry plus the ability to just go look. Losing that is a real cost, it just never appears in the pricing comparison.
Side note
How I'd actually decide
Estimate the duty cycle of the box you would otherwise rent. Peak requests per second, times CPU seconds per request, divided by the vCPUs you would provision. If that number is under about 40%, take the function and don't think about it again. If it's over 60%, run a container. Between the two, pick on operational fit rather than price, because the difference is a rounding error next to one engineer's afternoon.
Then override that on shape. Anything spiky, scheduled, event-driven or embarrassingly parallel is a function even when the arithmetic is close, because elasticity is the product you are buying. Anything with a long tail of duration, a big payload, a chatty database or a warm cache is a container even when the arithmetic looks fine, because you will spend the savings on workarounds. If the isolation model rather than the billing model is what you actually want, that is a containers versus virtual machines question and serverless is not the answer to it. And if the goal is latency rather than cost, the interesting move is usually pushing work outward into edge and distributed execution, not inward into a function in one region.
The honest summary is that serverless is an excellent default and a bad destination. Start there, because at low volume it is free and it removes an entire category of work. Watch your duty cycle. When it crosses 40% and stays there, you have stopped buying elasticity and started renting the same CPU at twice the price with extra rules attached.
Go pull one month of invocation counts and average duration out of CloudWatch and run the two lines. It takes ten minutes and it will either confirm you are fine or hand you the cheapest infrastructure win you will find this quarter.
Primary sources
- 1.PrimaryAWS Lambda Pricing. Amazon Web Services. $0.20 per million requests, $0.0000166667 per GB-second (x86, first tier), 1 million requests and 400,000 GB-seconds free per month, US East (N. Virginia). Retrieved August 2026
- 2.PrimaryLambda quotas. AWS Lambda Developer Guide. 900 second timeout, 128 MB to 10,240 MB memory, 1,769 MB equals one vCPU, 6 MB synchronous payload, 1,000 default concurrent executions, and the API Gateway throttle mismatch
- 3.PrimaryUnderstanding the Lambda execution environment lifecycle. AWS Lambda Developer Guide. Init, Invoke and Shutdown phases, the 10 second Init limit, cold starts in under 1% of invocations lasting under 100 ms to over 1 second, and initialization code as the largest latency contributor
- 4.PrimaryAWS Fargate Pricing. Amazon Web Services. $0.000011244 per vCPU-second and $0.000001235 per GB-second, Linux/x86, US East (N. Virginia). Retrieved August 2026
- 5.PrimaryUsing AWS Lambda with Amazon RDS. AWS Lambda Developer Guide. Amazon RDS Proxy manages a pool of shared connections so functions reach high concurrency without exhausting database connections
Frequently asked questions
- What is serverless computing?
- Serverless is a model where the cloud provider runs your code in a managed execution environment and bills you per invocation and per unit of run time, rather than renting you a machine by the hour. You still run on servers; you just do not provision, patch or scale them. The defining features are scale to zero, per-millisecond metering, and no operating system you are responsible for.
- Is serverless cheaper than running a server?
- Only below roughly 40% duty cycle. Using published AWS prices, a 512 MB Lambda function with a 120 ms average duration costs $0.0000012 per request, while an always-on 0.25 vCPU Fargate task costs about $9.01 a month, so the crossover lands near 7.5 million requests a month. Below that, serverless is cheaper. Above it, you are paying a premium for elasticity you are no longer using.
- How much does AWS Lambda cost?
- In US East (N. Virginia), Lambda charges $0.20 per one million requests and $0.0000166667 per GB-second of x86 compute in the first duration tier. The free tier covers one million requests and 400,000 GB-seconds each month. Memory is the only dial you set, and CPU scales with it, so at 1,769 MB a function has the equivalent of one vCPU.
- What causes a Lambda cold start?
- A cold start is the time AWS spends downloading your code, starting an execution environment, and running your initialization code before the handler ever executes. AWS says the largest contributor to that latency is the initialization code you wrote, which is affected by package size, imported libraries and how many connections you open at startup. Cold starts occur in under 1% of invocations and range from under 100 ms to over 1 second.
- What are the main limitations of AWS Lambda?
- The hard ones are a 900 second (15 minute) maximum execution time, a 6 MB synchronous request and response payload limit, 128 MB to 10,240 MB of memory, and a default quota of 1,000 concurrent executions per region. The soft one that hurts more in practice is database connections: a thousand concurrent function instances can each open their own connection, which is why AWS recommends Amazon RDS Proxy for production workloads.
Written by
Tech Talk News Editorial
Computer engineering background. Writes about software, AI, markets, and real estate, and the places where the three meet.
More about the author