Nobody picks a PaaS because a single container is expensive. Seven dollars for an always-on web service, two dollars for a tiny VM, twenty dollars of usage credit — every vendor's entry price is a bargain. Teams feel the bill later, when the same boring topology (an API, a background worker, a Postgres) lands on four different invoices and the totals differ by a factor of four — before a single gigabyte of growth. At bandwidth, the spread keeps going.
So let us do the thing PaaS comparisons usually skip: price one concrete, typical stack on every bill, line by line, at September 2026 rate cards. Here is the answer up front; every receipt follows below.
| Monthly total, reference workload, 100 GB egress | Price |
|---|---|
| Hetzner CX22 (whole stack on one flat box) | ~$5 |
| Fly.io (3 shared-CPU machines + volume) | ~$17 |
| Cloudflare baseline (Workers + R2 + external Postgres) | ~$25 |
| Render (2× Starter + Basic Postgres, Hobby workspace) | ~$37 |
| Railway (usage-metered, Pro minimum absorbed) | ~$46 |
| Vercel stack (Pro seat + Fluid functions + external DB + worker) | ~$68 |
Four disclosures ride along with that table, because a multiplier without them is marketing. First, this is a list-price recompute from public pricing pages and current rate-card records, not a scanned invoice — every rate below is cited so you can redo it, normalized at EUR→USD ~1.08, excluding VAT. Second, the Hetzner side is a single node with no HA, running all three services co-located, versus managed substrates with patching, dashboards, and multi-AZ options — the decision framework at the end prices what closing that gap costs. Third, ops and on-call time are excluded from both sides, which flatters Hetzner more than the vendors (their ops cost is bundled into their prices; Hetzner's is your evenings). Fourth, the workload is deliberately boring and always-on — no preview environments, one region, one seat — so this is the floor of the spread. Preview multipliers and extra seats widen it.
The reference workload: boring on purpose
Comparisons cheat by pricing different shapes on each side — serverless invocations on one, reserved VMs on another. Ours is fixed: a small production SaaS that many teams would recognize.
- API service: 0.5 vCPU, 512 MB RAM, running 24/7, serving web traffic.
- Background worker: same size, same uptime, chewing a queue.
- Postgres: 256 MB–1 GB, 10 GB of data, always on.
- Egress: 100 GB/month to the public internet at baseline, with sensitivity runs at 500 GB and 2 TB.
- Extras: none — one region, one developer seat where a vendor charges per seat, no preview environments.
Why always-on instead of scale-to-zero? Because the worker and the database cannot sleep — something is always running in this topology. Scale-to-zero only discounts the API tier, and the cold-start section prices exactly what that discount costs in latency. Fixing the shape is what makes the bills comparable.
Line by line: the four bills, plus two baselines
Railway: ~$46. Railway meters aggregate usage per second at $20/vCPU-month, $10/GB-month RAM, and $0.05/GB egress, on a Pro plan that is a $20/month usage minimum rather than an added fee. The API costs about $10 of vCPU plus $5 of RAM ($15); the worker doubles it ($30). A small Postgres lands around $10 of compute, 10 GB of volume at $0.15/GB-month adds $1.50, and 100 GB of egress adds $5. Usage totals roughly $46.50, which clears the $20 minimum — so the bill is ~$46. Railway's own comparison pages make the structural point: there is no per-service charge, so multi-service projects do not multiply fixed fees the way per-instance vendors do — but every gigabyte of RAM and egress is metered, and private-network discipline matters because public egress between services bills while *.railway.internal traffic does not.
Render: ~$37. Render charges per instance provisioned: a Starter web service and a Starter worker at about $7 each ($14), a Basic-256mb Postgres at roughly $6, and storage beyond the included 1 GB at $0.30/GB (9 GB extra ≈ $2.70). That is $22.70 before bandwidth — matching Render's own guidance that a Starter web service plus Basic Postgres runs about $13/month before bandwidth and storage growth. The Hobby workspace includes only about 5 GB of outbound bandwidth, and overage bills at $0.15/GB, so 95 extra GB adds $14.25. Total: ~$37. Note the shape of this bill: compute is fixed and predictable, and nearly 40% of the total at baseline is bandwidth, not compute.
Fly.io: ~$17. Fly Machines bill per second while started: a shared-cpu-1x machine with 256 MB runs about $1.94/month with region scaling up to about $3.14, and 512 MB machines land around $4. Two app machines ≈ $8; a Postgres machine around $6 plus a 10 GB volume at $0.15/GB-month ($1.50). Egress is the cheapest of the four at $0.02/GB in North America and Europe — 100 GB costs $2. Total: ~$17.50. Two honest footnotes: there is no free tier for new organizations since late 2024, and Fly's regional egress split (up to $0.12/GB in Africa and India) means a global user base reprices the cheapest line on this page.
Vercel stack: ~$68. Vercel needs decomposing because it does not natively host two of the three services: persistent workers and Postgres live elsewhere. Start with Pro at $20 for one seat, then Fluid-compute functions billed on active CPU at $0.128/hour plus provisioned memory and $0.60 per million invocations. Assume 5 million invocations at 100 ms of active CPU each with 1 GB provisioned: 139 CPU-hours ≈ $17.78 of active CPU, ≈ $1.47 of memory, $3 of invocations — $22.25 for the API tier, with 100 GB of bandwidth inside the included 1 TB. Then the parts Vercel does not sell you: Postgres via Neon Launch ($19), a worker via a Render Starter ($7). Total: ~$68. This is the correct comparison, not a stacked deck — a team that "runs on Vercel" still runs a database and a worker somewhere, and the invoice for the architecture is the sum of all three vendors.
Cloudflare baseline: ~$25. Workers Paid ($5) serves the API tier with zero egress fees, R2 holds 10 GB at $0.015/GB-month with $0 egress, and the same external Neon Postgres ($19) covers what Workers does not do. Total: ~$25. It belongs in the table as the control group: the price of compute when the bandwidth meter is removed entirely — and the reason R2-style $0 egress keeps appearing in migration stories.
Hetzner CX22: ~$5. One CX22 (2 shared vCPUs, 4 GB RAM, 40 GB NVMe) at about €4.59/month after the June 2026 repricing — roughly $5 — fits all three services with headroom, and 20 TB of included traffic means the egress meter never moves. Two nodes for HA double it to ~$10. That is the flat number the whole spread collapses to.
Egress sensitivity: where 4x becomes 5x and keeps going
At the 100 GB baseline the four PaaS bills run ~$17 (Fly.io) to ~$68 (Vercel stack) — about a 4x spread on identical compute. Now grow only the bandwidth and recompute. Nothing else moves.
| Monthly total at… | 100 GB egress | 500 GB egress | 2 TB egress |
|---|---|---|---|
| Railway ($0.05/GB) | ~$46 | ~$66 | ~$141 |
| Render ($0.15/GB overage) | ~$37 | ~$97 | ~$322 |
| Fly.io ($0.02/GB NA/EU) | ~$17 | ~$25 | ~$55 |
| Vercel stack ($0.15/GB past 1 TB) | ~$68 | ~$68 | ~$218 |
| Hetzner CX22 (20 TB included) | ~$5 | ~$5 | ~$5 |
Three things fall out. First, the title's "5x" is crossed on the way to 2 TB: at 500 GB, Render (~$97) already costs nearly 4x Fly.io (~$25), and by 2 TB the Render-to-Fly.io gap is ~$322 versus ~$55 — almost 6x, on the same three containers. Second, the ranking inverts with scale: Render is cheaper than Railway at baseline and nearly 2.3x more expensive at 2 TB, because a $0.15/GB overage compounds three times faster than a $0.05 one. Third, Vercel's included 1 TB of bandwidth is genuinely load-bearing — the Vercel stack is flat until 1 TB and then climbs at the same $0.15 slope as Render. The general rule: below ~200 GB/month you are buying compute and the spread is about instance pricing; above it you are buying bytes and the spread is about egress. Every "surprise bill" postmortem you have ever read is a team discovering which side of that line they were on.
The Cloudflare footnote sharpens the point: S3 egress at $0.09/GB versus R2 at $0 means any workload that serves uploads, images, or artifacts at volume pays a bandwidth tax on AWS-shaped pricing that simply does not exist on R2 or on a 20 TB Hetzner box. Egress is the one line item where the PaaS premium is unbounded — compute has a ceiling per instance, but bytes do not.
Cold-start math: what scale-to-zero actually pays you
The standard rebuttal to this whole exercise is scale-to-zero: serverless tiers do not bill idle, so always-on math overstates the cost. True — and the discount has a price measured in milliseconds. Here is the wake-latency ladder for the API tier, best to worst:
| Tier | Cold wake | What idle costs |
|---|---|---|
| Hetzner (always on) | 0 ms — nothing sleeps | The full $5, busy or idle |
| Cloudflare Workers (isolates) | Single-digit ms; effectively no container boot | $0 at zero traffic within included requests |
| Vercel Edge / warm Fluid functions | Edge under 30 ms; warm functions ~100 ms-scale | Billed on active CPU only — I/O wait is free |
| Railway serverless sleep | Seconds-scale container resume | $0 compute while asleep |
| Fly.io stopped Machines | ~2–6 s stop/start; suspended rootfs still bills $0.15/GB | Per-second billing while started only |
| Render free sleep | ~1 min wake after 15 min idle | Free tier, but the worker and database cannot sleep with it |
The honest accounting: scale-to-zero discounts exactly one tier of a three-tier stack. The worker polls and the database persists — both bill 24/7 on every platform here. On Railway that bounds the sleep savings to roughly the $15 API slice; on Render the free tier cannot host this workload at all (sleeping Postgres means no database). And the latency cost lands on your p99, not your invoice: a 2–6 s Fly wake or a 60 s Render wake is invisible in averages and brutal in tail-latency plots. Teams that quote the sleeping price while serving latency-sensitive traffic are pricing a different product than the one their users experience.
The decision framework, and the flat number
With receipts in hand, the choice compresses to workload shape:
- Spiky side project, tolerant users: scale-to-zero wins — Railway serverless or Fly stopped machines drive the API tier toward $0, and Fly's $0.02/GB egress keeps small bandwidth cheap. Watch the Postgres floor: the database is always the minimum bill.
- Steady small SaaS under ~200 GB/mo: fixed instance pricing wins — Render's $37 or Fly's $17 beats metered usage, and predictability is worth more than the last $10 of optimization.
- Bandwidth-heavy past ~500 GB/mo: egress dominates everything — Fly.io's regional rates, Cloudflare's $0 egress, or owned hardware. This is where Render's $0.15/GB overage turns a $37 stack into a $322 one.
- Global edge with framework-native DX: Vercel's premium buys Edge latency and Fluid I/O-free billing, not cheap containers — price it knowingly, keep the database and worker bills in the same spreadsheet, and use the 1 TB bandwidth inclusion deliberately.
- Steady SaaS where you can own ops: one CX22 at ~$5 (two at ~$10 for HA) collapses the entire spread to a single flat number with 20 TB of headroom. The premium you give up is managed patching, one-click previews, and someone else's on-call — worth it for many teams, not free, and never $0 of your time.
That last line is the point of the exercise. The 5x spread is not a verdict that PaaS is a scam — it is the price of five different answers to "whose pager goes off." Metered usage, fixed instances, edge serverless, and owned hardware each win a different workload shape, and the wrong match costs 4–6x before traffic even grows. Price your actual bytes, your actual sleep schedule, and all three tiers — then pick the meter that fits.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.



