The cost shape of serverless, and when it stops making sense
Per-request pricing is an excellent deal until it is not, and the crossover is arithmetic.
Serverless pricing is genuinely good for the workload it was designed for: spiky, unpredictable, mostly idle. The mistake is assuming that property survives growth.
The crossover is arithmetic, not ideology
Per-request pricing beats per-hour pricing while utilisation is low. As requests grow, the per-request bill grows linearly while a provisioned instance stays flat. There is a crossover point and it is calculable from your own numbers rather than a matter of taste.
Work it out for your busiest three functions. Most teams find at least one already past it.
Idle is where the saving actually lives
The value is not cheap compute, it is not paying for idle. A workload busy most of the time was never a good candidate. A workload that runs twice an hour is an excellent one, and moving it to an always-on instance to save money usually does the opposite.
Price the whole path, not the function
Function cost is often the smaller half. Database connections, gateway invocations, data transfer and log ingestion frequently exceed compute. A migration justified on function cost alone tends to disappoint.
Cold starts are a cost that is not on the invoice
Latency budget spent on cold starts is paid by users rather than finance. If mitigating it means provisioned concurrency, that is an always-on charge and the crossover maths changes accordingly.
Serverless is not cheaper or more expensive in general. It has a cost shape, and the question is whether your workload matches it. Where they diverge, migrate the specific function rather than relitigating the architecture.