Self-Hosting vs Serverless: The Real Cost Breakdown
Serverless is cheap until it is not, and a VPS is simple until 3 a.m.
Key takeaways
- Serverless wins on spiky and very low traffic. Always-on wins on steady, substantial load.
- Serverless does not remove operations — it swaps infrastructure work for platform expertise.
- Measure your peak-to-median ratio before choosing. Above ~5 favours serverless.
The comparison nobody publishes honestly
Most self-hosting versus serverless comparisons are written by someone selling one of the two. The vendor content shows serverless costing almost nothing at low traffic. The independent blog posts show a horror story where a misconfigured function generated a five-figure invoice overnight. Both are real, and neither tells you what your workload will cost.
The honest answer is that the decision hinges on three variables specific to you: how spiky your traffic is, how much operational time you can afford, and how predictable your costs need to be. Get those three right and the architecture follows.
What each model actually means
| Factor | Self-hosting | Serverless |
|---|---|---|
| You pay for | Time (always on) | Invocations + duration |
| Steady traffic | Cheaper | Expensive |
| Spiky traffic | Wasteful | Excellent |
| Cost predictability | Fixed | Variable |
| Ops burden | Yours | Platform’s |
| Cold starts | None | Possible |
The vocabulary has drifted, so it is worth being precise.
Self-hosting here means you rent compute that runs continuously — a virtual private server, a dedicated machine, or a managed container platform where you choose the instance count. You pay for time, whether or not anyone visits. You are responsible for the operating system, runtime, deployment, monitoring and security patching.
Serverless means you deploy functions or containers that the platform starts on demand and stops when idle. You pay for invocations and execution duration. The platform handles capacity, patching and scaling. You give up control over the runtime environment and accept constraints on execution time, memory and local state.
The critical difference is not technical. It is that one model converts operations work into money, and the other converts money into operations work.
Cost: where the crossover actually sits
Serverless pricing is genuinely excellent at two extremes: very low traffic and very spiky traffic. It becomes expensive in the middle, where load is steady and substantial.
Consider the shape rather than the exact numbers, which change constantly.
- A hobby project serving a few thousand requests a month usually costs nothing on serverless free tiers, versus a fixed monthly fee for the smallest VPS. Serverless wins clearly.
- A steady production API handling sustained traffic around the clock frequently costs several times more on per-invocation pricing than on two modest always-on instances. Self-hosting wins clearly.
- A spiky workload — a ticketing system, a campaign landing page, a service with a daily batch peak — is where serverless earns its premium. Provisioning always-on capacity for the peak means paying for idle capacity the rest of the time.
Two costs are consistently underestimated in serverless budgets. The first is data transfer, particularly egress, which is often billed separately and can exceed compute cost for media-heavy applications. The second is the surrounding managed services — managed databases, queues, object storage, API gateways and log retention — which the function itself needs to be useful.
Two costs are consistently underestimated in self-hosting budgets as well. The first is your time: patching, certificate renewal, log rotation, upgrades and the occasional 3am incident are real expenses even when no invoice arrives. The second is redundancy. A single server is not a production architecture; comparing one VPS against a globally distributed serverless platform is not comparing like with like.
Cold starts, and when they genuinely matter
Cold starts are the most discussed serverless drawback and frequently the least relevant one. For background jobs and webhooks, nobody is waiting.
Cold starts are the most discussed serverless drawback and frequently the least relevant one.
A cold start occurs when a request arrives with no warm instance available, so the platform must initialise a runtime. The penalty ranges from a few milliseconds for lightweight edge runtimes to several seconds for a large container with a heavy dependency tree and a database connection to establish.
Whether that matters depends entirely on context:
- It matters a great deal for user-facing requests on the critical path, where an occasional multi-second delay is visible and damaging.
- It matters very little for background jobs, webhooks, scheduled tasks and asynchronous processing, where nobody is waiting.
- It is largely solved by edge runtimes for simple request handling, and by provisioned concurrency — which reintroduces a fixed cost and therefore erodes the original economic argument.
You can substantially reduce cold-start impact by minimising dependencies, avoiding heavyweight initialisation at module scope, and using connection pooling proxies for databases rather than opening a new connection per invocation.
Operational burden is the real deciding factor
Teams choose infrastructure on price, then live with the operational consequences for years. Reverse that order and the decision usually becomes obvious.
Teams choose infrastructure on price and then live with the operational consequences for years. Reverse that order and the decision usually becomes obvious.
Self-hosting means you own:
- Operating system and runtime patching, on a schedule you actually keep
- TLS certificate provisioning and renewal
- Log collection, rotation and retention
- Monitoring, alerting and someone to receive the alerts
- Backup creation and, more importantly, tested restoration
- Capacity planning and the response when you get it wrong
None of this is difficult in isolation. Collectively, it is a steady tax that scales with the number of services you run, and it is paid by whoever is least able to refuse it.
Serverless removes most of that list and replaces it with a smaller but sharper one: understanding the platform's limits, debugging distributed execution across many short-lived invocations, managing cold paths, and controlling spend. Observability is genuinely harder because there is no long-lived process to inspect.
The honest summary is that serverless does not eliminate operations. It substitutes infrastructure operations for platform expertise.
Lock-in, and how much to worry about it
Lock-in concerns are frequently overstated for stateless compute and understated for everything else.
A function containing ordinary application logic is straightforward to move. A system built around a specific provider's queues, event bus, identity service, managed database dialect and infrastructure-as-code definitions is not. The compute layer is rarely the trap; the surrounding services are.
If portability matters, keep business logic in plain, framework-agnostic modules and confine provider-specific code to a thin adapter layer at the edges. This is good design regardless of hosting model, and it makes migration a matter of rewriting adapters rather than rewriting the product.
A decision framework you can apply in ten minutes
Choose serverless when:
- Traffic is unpredictable, seasonal or heavily spiked
- The team is small and has no dedicated operations capacity
- Workloads are event-driven, asynchronous or scheduled
- You are validating an idea and want to avoid fixed costs before product-market fit
- Global low-latency delivery matters and you do not want to manage regions
Choose self-hosting when:
- Traffic is steady and reasonably predictable
- Costs must be fixed and forecastable, with no possibility of a runaway bill
- Workloads are long-running, stateful, or require persistent connections such as WebSockets
- You need specific runtimes, GPU access, or unusual system-level dependencies
- Data residency or compliance requirements constrain where and how data is processed
Choose static hosting — a third option people forget — when your application is fundamentally content. A blog, documentation site or marketing site rendered to static HTML and served from a CDN is faster than both alternatives, costs almost nothing, and has essentially no operational surface. Reach for compute only for the parts that genuinely need it, such as a contact form or a search endpoint.
The hybrid pattern most mature teams end up with
This is not fence-sitting. It is matching each workload’s shape to the pricing model that suits it.
In practice the answer is rarely exclusive. A common and sensible arrangement looks like this:
- Static assets and pre-rendered pages on a CDN, because that is unbeatable on cost and latency
- The steady core API on always-on instances, because predictable load is cheaper that way
- Spiky, bursty or scheduled work on serverless functions, because that is exactly what they are good at
- Managed services for databases and object storage, because self-managing stateful systems is where most operational pain concentrates
This is not fence-sitting. It is matching each workload's shape to the pricing model that suits it.
How to decide without guessing
Instrument before you architect. Collect two weeks of request data and answer three questions: what is the peak-to-median ratio, what is the median response duration, and what proportion of requests are user-facing?
A peak-to-median ratio above roughly five makes serverless economics attractive. A ratio near one, with meaningful sustained volume, makes always-on capacity cheaper. Short durations favour per-invocation pricing; long ones penalise it heavily.
Then model the cost of both options against those numbers rather than against a generic example. The calculation takes an afternoon and prevents a migration you would otherwise perform twice.