The question this answers
Does this component bill me for existing or for being used, and at what traffic does the answer flip?
The team must choose between running the notification service on always-on instances and running it as functions. Traffic is bursty: near zero overnight, with a large spike when the daily digest goes out. Both options meet the latency requirement. The decision is therefore economic, and it has to be made in a way that survives traffic growing tenfold.
A way to reason about which pricing shape fits a traffic profile, and a habit of stating the crossover point as a range rather than pretending to know a price.
Two shapes, and what each one punishes
A fixed-shape resource bills for existing. An instance costs the same at 3% utilization as at 80%, which means fixed pricing punishes *idleness* and rewards steady, high utilization. A variable-shape resource bills for use — invocations, vCPU-seconds, gigabytes processed — which means it punishes *volume* and rewards workloads that genuinely do nothing most of the time.
Almost nothing is purely one or the other, and the mixed cases cause most of the confusion. A managed database is fixed for the instance and variable for storage and I/O. A load balancer is fixed hourly and variable per gigabyte. A serverless function is variable per invocation and, if it uses provisioned concurrency to avoid cold starts, fixed for the warm capacity — which is the point at which "serverless is cheap because you pay for what you use" stops being true and nobody updates their mental model.
The consequence for design is direct: match the shape to the traffic profile. Steady baseline traffic on variable pricing pays a premium for elasticity it never uses. Spiky or intermittent traffic on fixed pricing pays for capacity that sits idle between spikes. Most real systems are both — a steady baseline plus bursts — which is why the strongest pattern is often a modest fixed baseline for the steady part with variable capacity absorbing the peaks.
Bars are relative weights, not currency. Real rates depend on provider, region, commitment and volume.
The crossover, and why nobody can quote it
There is a traffic level at which the two shapes cost the same, and below it variable wins while above it fixed wins. Everyone wants that number and nobody can give it to you honestly, because it depends on the provider, the region, the memory allocated per invocation, the duration of each invocation, the commitment discount on the instance, and whether provisioned concurrency is in play. Any article quoting a universal crossover is quoting one workload on one provider on one day.
What *is* transferable is the method. Express both options as a function of monthly request volume: variable cost is roughly requests × cost-per-request, fixed cost is roughly instances × hours × rate, and the crossover is where the lines meet. Then, and this is the part usually skipped, ask what happens at ten times the volume. Variable pricing scales linearly forever, so a workload that grows keeps paying proportionally. Fixed pricing scales in steps and improves per unit as utilization rises. A choice that is correct at launch is frequently wrong two years later, and the migration between them is not free.
The worksheet below is the shape of that comparison with invented values. The point is not the numbers; it is the structure — per-request economics on one side, per-hour economics on the other, and the third row that most comparisons omit entirely, which is the fixed plumbing both options need regardless.
low traffic steady traffic high traffic
1M req/month 50M req/month 500M req/month
VARIABLE (functions)
invocations 1 unit 50 units 500 units
provisioned warm 0 2 units 2 units
total 1 52 502
FIXED (instances)
2 small instances 20 units 20 units -
8 medium instances - - 160 units
utilization ~2% ~35% ~70%
total 20 20 160
---------------------------------------------------------------
cheaper VARIABLE (20x) VARIABLE (2.6x) FIXED (3.1x)
shared by both, and usually left out of the argument:
load balancer hours, NAT hours, database instance, log ingestion
COST-VARIES: crossover depends on provider, region, memory per invocation,
invocation duration, commitment discount and provisioned concurrency.
Measure yours; do not inherit this table.Choosing a shape, not a technology
Framing the decision as "serverless versus containers" invites a religious argument. Framing it as "which pricing shape fits this traffic profile" makes it answerable, and it produces the right answer for reasons that survive re-examination.
Three traffic profiles cover most cases. Intermittent workloads — an admin tool, a nightly job, a webhook handler — spend most of their life idle and are almost always cheaper on variable pricing, sometimes by an order of magnitude. Steady workloads with a predictable baseline are cheaper on fixed pricing with a commitment, because you are buying the utilization you already have. Spiky workloads with a real baseline are best served by both: fixed capacity sized to the baseline, variable capacity absorbing the peak.
Two caveats keep this honest. Cost is rarely the deciding factor on its own — Serverless Trade-offs covers cold starts, execution limits, the connection problem against a pooled database and the observability gaps, any of which can outweigh the money. And a commitment discount is a bet: it lowers the fixed rate substantially in exchange for a one-to-three-year promise, so it is only correct if you are confident the workload still exists in that shape when the term ends.
| Traffic profile | Cheaper shape | Why | What to watch |
|---|---|---|---|
| Intermittent — idle most of the day | Variable | You pay for the minutes it runs instead of the hours it exists | Cold starts on the first request after a quiet period — see Startup Time & Cold Start |
| Steady baseline, predictable | Fixed, with a commitment | High utilization makes the per-hour rate cheap per request | A commitment outliving the architecture it was bought for |
| Spiky with a real baseline | Both — fixed baseline, variable peak | Each shape covers the part it is good at | Two systems to operate and two cost models to reason about |
| Unpredictable and growing fast | Variable first, revisit quarterly | Elasticity is worth a premium while the shape is unknown | Linear scaling means the bill grows exactly as fast as traffic |
| Batch, tolerant of interruption | Variable on interruptible capacity | Spot or preemptible capacity is dramatically cheaper for restartable work | Interruption handling has to actually work, not just exist |
| Steady and very large | Fixed, and consider owning hardware | At sustained high utilization the cloud premium becomes visible | The engineer-hours to run it — see On-Premises vs Cloud |
Key points
- Fixed pricing bills for existing and punishes idleness; variable pricing bills for use and punishes volume.
- Most components are mixed, and provisioned concurrency is the classic case of a variable line quietly becoming fixed.
- The crossover point is real and unquotable: it depends on provider, region, memory, duration, commitment and warm capacity.
- Compare at today's traffic and at ten times today's traffic. Variable scales linearly forever; fixed improves per unit as utilization rises.
- The shared plumbing — load balancer, NAT, database, logs — is present in both options and is what makes flattering comparisons possible.
- Choose the shape that matches the traffic profile, then check whether the non-cost trade-offs veto it.
The loop, answered
Every field is required, which is why no lesson here can recommend something without saying what it costs and what simpler thing to consider first.
- • Fixed resources meter wall-clock existence: the instance is billed per hour whether it serves one request or a million.
- • Variable resources meter events and resource-seconds: invocations, allocated memory multiplied by duration, gigabytes processed.
- • Commitments apply a discounted rate to a promised minimum of fixed usage over a term, transferring forecast risk to you.
- • Interruptible capacity offers a large discount in exchange for the provider reclaiming it with short notice, which suits restartable batch work.
- • Mixed resources run both meters at once, which is why a single "is this fixed or variable" answer is usually wrong for any real component.
- • Write down the traffic profile before choosing: requests per second at the peak, at the median, and overnight.
- • Model both shapes at current volume and at 10×, and record the assumptions next to the numbers so the model can be re-checked later.
- • Include the shared plumbing in both columns. Omitting it is the most common way these comparisons mislead.
- • Revisit quarterly while traffic is growing. The correct shape changes, and noticing late costs a migration.
- • Buy commitments only for the portion of the baseline you are confident about, and stagger their end dates so you are never fully locked.
- • Serverless adopted for cost reasons on a steady high-volume workload, where linear per-request pricing quietly exceeds the instances it replaced.
- • Provisioned concurrency added to fix cold starts, converting the pricing shape without anyone revisiting the original comparison.
- • A commitment purchased for an instance family the team migrates away from six months later, paid in full regardless.
- • Fixed capacity sized for the peak and idle the rest of the time, which is the fixed-shape version of the same mistake — see Idle Capacity: Headroom or Waste?.
- • A runaway loop on variable pricing: recursive invocations or a retry storm billing in hours what was budgeted for a month, with no capacity ceiling to stop it.
- • Variable cost is linear in volume with no economies of scale unless you negotiate them, so growth translates directly into bill growth.
- • Fixed cost is stepwise and improves per request as utilization rises, which is why mature high-volume systems tend to drift toward fixed shapes.
- • The crossover moves downward as commitment discounts deepen and upward as per-invocation efficiency improves.
- • The dimension that runs out first on variable pricing is often a concurrency quota rather than money — an availability failure that looks like a cost decision.
- • Variable pricing has no natural ceiling, which makes cost a denial-of-wallet target: an attacker who can trigger invocations can generate spend. Rate limits and concurrency caps are a security control here, not only a performance one.
- • Concurrency caps protect the bill and can throttle legitimate traffic. Decide deliberately which failure you prefer.
- • Interruptible capacity for anything holding sensitive state needs the same encryption and clean-shutdown handling as permanent capacity, despite feeling disposable.
- • Fixed: instance-hours, reserved capacity, provisioned concurrency, load balancer and NAT hours.
- • Variable: invocations, resource-seconds, gigabytes transferred and processed, per-request storage operations.
- • Mixed components run both meters; read every line item for its shape rather than assuming one per service.
- • Every number in this lesson is invented to show a structure. Actual rates and the crossover they imply differ by provider, region, tier and commitment.
- • Cost per thousand requests, tracked over time — the metric that reveals whether a rising bill is growth or decay in efficiency.
- • Utilization on fixed capacity, which is what tells you whether the fixed shape is being earned.
- • Invocation count and average duration on variable capacity; duration is the multiplier people forget is in the formula.
- • Commitment coverage and expiry dates, so a term ends deliberately rather than by surprise.
- • The signal that lies: a low monthly bill on a new variable-priced service. It is low because volume is low, and it will track volume exactly.
- • Do nothing yet. If the bill is small relative to engineering time, keep the shape that is simplest to operate and revisit when the number matters.
- • A single small always-on instance is often cheaper and vastly simpler than a serverless architecture for a low-traffic service, once you count the plumbing.
- • Scheduled scaling on fixed capacity captures much of the variable benefit for a predictable daily curve, without changing the execution model.
- • Interruptible capacity for batch work usually beats both shapes on price, provided the work is genuinely restartable.
- • Variable buys elasticity and zero idle cost; costs linear scaling with no ceiling, cold starts, execution limits and a bill exposed to abuse.
- • Fixed buys predictable spend and no cold starts; costs paying for idle capacity and the operational work of capacity planning.
- • Commitments cut the rate and remove the freedom to re-architect during the term.
- • Running both shapes covers each profile well and doubles the operational and cost models the team must hold.
Where the bill actually comes from
fixed weight is committed at provision time; usage weight follows the workload. idle = 100% − 35% used → headroom 25% (chosen) + waste 40% (not chosen)
What people believe, and what is true
Serverless is cheaper.
Cheaper for intermittent workloads, frequently more expensive for steady high-volume ones. Linear per-request pricing has no economies of scale.
Pay-per-use means you cannot overspend.
It means spend is unbounded by design. A retry storm or a recursive invocation bills at full rate with no capacity ceiling to stop it.
We picked the cheaper option, so we are done.
The crossover moves with traffic. A choice that was correct at launch is often wrong at 10× volume, and switching later costs a migration.
A commitment discount is free money.
It is a bet on your own forecast. Reserved capacity for an architecture you abandon is paid in full for the remaining term.