Skip to main content

The 5x PaaS Pricing Spread: What One API + Worker + Postgres Costs on Railway, Render, Fly.io, Vercel — and a Flat Hetzner Box

11 min readDora NodaDora Noda
Share
On this page

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 egressPrice
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 egress500 GB egress2 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:

TierCold wakeWhat idle costs
Hetzner (always on)0 ms — nothing sleepsThe 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 functionsEdge under 30 ms; warm functions ~100 ms-scaleBilled on active CPU only — I/O wait is free
Railway serverless sleepSeconds-scale container resume$0 compute while asleep
Fly.io stopped Machines~2–6 s stop/start; suspended rootfs still bills $0.15/GBPer-second billing while started only
Render free sleep~1 min wake after 15 min idleFree 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.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex