TL;DR: Per-invocation pricing is a bet on workload shape, not a discount. Functions win when utilization is low and traffic is spiky; steady high-throughput services pay a real premium per unit of work. Decompose the bill, do the crossover arithmetic out loud, and count the lines nobody models such as NAT, logs and chatty fan-out.
How to approach it
Ask for the traffic shape first: requests per second, concurrency profile, execution duration, memory footprint. Everything else follows from utilization. Then give the bill anatomy, the crossover math, and the decision rule.
A strong answer
For an illustrative AWS Lambda x86 first-tier comparison in US East (N. Virginia), use $0.20 per million requests and $0.0000166667 per GB-second before free-tier allowances, discounts and other charges. Check the current Lambda pricing for region, architecture and tier. At that compute rate, a one-GB function continuously executing for 30 days costs about $43.20, excluding requests and ancillary services. Compare against an explicitly sized alternative with equivalent throughput and availability.
A synthetic webhook workload with 50,000 invocations, 400ms duration and 0.5GB allocated memory consumes 10,000 GB-seconds: about $0.1667 compute plus $0.01 requests before free tier. At 300 concurrent one-GB executions continuously busy for 30 days, compute alone is about $12,960. These assumptions do not establish a universal utilization crossover; benchmark the VM/container alternative and include operations cost.
Then the lines nobody models:
| Workload | Serverless wins | Containers win |
|---|---|---|
| Spiky or unpredictable traffic | Pay nothing between bursts | Idle capacity bills continuously |
| Cron, webhooks, event glue | Utilization near zero | Minimum viable host still costs real money |
| Steady high throughput | Per-GB-second premium compounds | Multiplexing amortizes the host |
| Long-running jobs | Execution ceilings force redesign | No time limit, cheaper hour rates |
Hidden charges routinely exceed compute. NAT gateways for outbound calls carry fixed hourly cost per zone plus per-gigabyte processing, brutal for chatty functions. Verbose debug logging bills more than the compute underneath it on plenty of production functions. Splitting one endpoint into eight functions multiplies invocations eightfold, so granularity itself has a price, as do orchestrators charging per state transition.
Memory is the counterintuitive lever: price scales linearly with memory but allocated CPU scales with it too, so doubling memory and exactly halving billed duration leaves compute cost unchanged at a linear rate. A larger speedup can reduce compute cost; a smaller one increases it. Find the optimum empirically with power-tuning runs rather than guessing; measure billed duration and total charges for each configuration.
Honest position: functions for event glue, spiky endpoints and anything mostly idle; containers for steady core services. One reversal condition: a tiny team with no operations capacity can rationally overpay at utilization levels where the arithmetic favors containers, because unpatched-host hours are real money too.
What interviewers probe next
"Your log line dwarfs your compute line." Sample, filter by level, set retention windows, ship errors hot and everything else to cheap storage; this is usually the fastest cut available.
"Provisioned concurrency erased the savings." Paying for warm capacity around the clock is a container subscription with extra steps; re-run the comparison honestly, or scope warmth to business hours only.
"A team split one endpoint into eight functions." Coarsen the unit of work and batch transitions inside the orchestrator; invocation count is an architecture output, not fate.
Common mistakes
Comparing compute rates while ignoring invocation multiplication engineered in by chatty design.
Treating free-tier intuition as production economics.
Forgetting execution ceilings push long jobs to containers regardless of price.
Assuming zero ops; IAM, observability and deployment still consume engineer hours every month.