Skip to main content

One Developer, Many Side Projects, One Railway Bill: Where Per-Service Metering Loses to a Flat Hetzner Box

11 min readDora NodaDora Noda
Share
On this page

Sixteen resources, one Railway bill, $17.57 — and $12.49 of it is memory while CPU rounds to $0.30. That ratio, pulled from a real account instead of a rate card, is the most useful number in the 2026 PaaS pricing debate: it says idle side-project sprawl is billed by the gigabyte held, not the compute burned. Once you see the bill that way, the question stops being "which platform is cheapest" and becomes "at how many projects does per-service billing lose to one flat box" — and the answer is a crossover point, not a verdict table.

The anchor comes from Zainan Victor Zhou's Post-Heroku PaaS Landscape guide, which prices Railway, Fly.io, Render, Heroku, and self-hosting for a one-person company running many small projects, grounded in his own account: 8 projects, 16 resources (9 services, 5 Postgres databases, 2 Redis caches), ~$17.57/month on Railway's $5 Hobby plan. This post works that anchor forward into the extension the guide invites: all-in cost per project — compute plus egress plus build minutes — metered against a flat Hetzner box, with the sprawl crossover named per pricing philosophy.

The verdict up front​

Pin the reference vector before any math, so every cell below is checkable. One tiny project = one mostly-idle web service + one small Postgres database holding ~200MB of RAM, averaging ~0.005 vCPU (CPU cost rounds to ~$0), moving ~0.5GB of egress, keeping ~200MB of volume, and shipping 4 builds a month at ~3 minutes each. That footprint is conservative against the anchor: $17.57 across 16 resources blends to ~$1.10/resource/month, so ~$2.20/project/month is the metered number to beat.

Every cell below is all-in: compute (RAM + CPU) + egress + builds + volumes. Prices observed September 2026; all four hosted vendors replan regularly, so re-verify before budgeting.

N projectsRailway (metered)Fly.io (metered, self-hosted PG)Render ($7 + $6 floor)Heroku ($5 + $5 floor)Flat box (rental only)
1$5.00 (floor: $2.16 usage < $5 credit)~$4$13$10~$7 (Box A, mostly idle)
5~$11~$20$65$50~$7 (Box A)
10~$22~$40$130$100~$7 (Box A)
50~$108~$202~$654$500~$19 (steps to Box B)

The flat column is stepped hardware, not one magic number. Box A is a 4GB Hetzner cloud box (CX23/CAX11 class, ~$7/month including IPv4), which fits about 15 tiny pairs after OS overhead — so there is a capacity cliff at N≈16: Box A is full and you must step up. Box B is a 16GB box (CX43 class, ~$19/month), good for roughly 60 pairs. The flat column is labeled honestly: box rental only, no ops time, no management plane. The loaded version comes later in this post.

Two crossovers fall straight out of the table. Fixed-floor pricing (Render, Heroku) loses on raw dollars at N=1: a single $13 project already costs more than the $7 box it could live on. Metered pricing loses at N≈3–4 on Railway's blended rate and N≈2 on Fly.io's always-on ceiling — though Fly's true idle cost with autostop bills less than the ceiling, which pushes its line out.

If those numbers feel absurdly early, that is the point: raw dollars were never the reason to stay hosted. The reason is the burden math later in this post, and the crossover that matters lands much later.

Why the bill is memory, not CPU​

The anchor's line items deserve a second look because they name the actual unit of sprawl cost. Of the ~$17.57 estimate, memory is $12.49, CPU is $0.30, egress is $0.11, volumes are $0.22, and backups round to zero. Memory outspends CPU forty-to-one. Sixteen resources averaging ~78MB each is an account full of processes doing nearly nothing — and "nearly nothing, held in RAM, all month" is exactly what per-second metering still charges for, because held memory is reserved whether or not the CPU fires.

That ratio reframes the whole comparison into cost per gigabyte held. Railway meters RAM at roughly $10/GB-month. Box B holds 16GB for ~$19/month, or roughly $1.20/GB-month — an 8x spread on the exact resource idle sprawl consumes.

CPU, the input every benchmark optimizes, is a rounding error on both sides: $0.30 on the anchor, $0 on the box. Anyone pricing sprawl by vCPU is measuring the wrong meter.

This is also why the fixed-floor rows multiply so brutally. A $13 Render floor is not $13 of compute — it is $13 for owning the service slot, and the slot costs the same whether the project serves one request a day or a million. Ten quiet projects are ten slots. The floor has no idle discount, so project count becomes the bill directly.

The three lines the rate card hides​

Compute-only math flatters every platform, so the extension prices the other three lines per project instead of waving them off.

Egress. The anchor's $0.11 says side projects barely move bytes — until one of them gets users. At the pinned 0.5GB/project, egress adds ~$0.03 on Railway ($0.05/GB), $0.01 on Fly.io ($0.02/GB in North America and Europe), and $0 on Render inside its 5GB included allowance. But push one project to 100GB and the lines diverge hard: Railway adds $5/project (tripling its per-project cost), Render adds roughly $14 past the allowance (more than the $13 floor itself), Fly.io adds ~$2 — and Heroku and the box add $0, since Heroku bundles bandwidth into the dyno price and Hetzner bundles terabytes of included traffic. Egress is the sensitivity that can single-handedly move a crossover by an order of magnitude, which is why the table pins it low and this section prices it high.

Build minutes. Every OPC deploys each project a few times a month, and the bill treats those minutes differently per vendor. Railway's docs state it plainly: "Service builds are free. Railway does not charge for build CPU, memory, base-image downloads, image exports, or image storage." Fly.io's remote builders are likewise free. Render meters build-pipeline minutes past an included allowance (500 minutes on Hobby, then $5 per 1,000) — at 12 minutes per project per month, N=50 burns 600 minutes and owes ~$0.50. Honestly sized, builds are pennies at OPC scale on every platform — but only because someone checked; a CI-heavy monorepo deploying hourly would make Render's line real while Railway's stayed $0.

One database per project? The 1:1 service-to-DB unit is the guide's clean-math assumption, and it is the load-bearing one for the floor rows. Collapse ten toy databases into one shared Postgres and Render's N=10 drops from $130 to $76 (ten $7 services, one $6 database) — still 10x the box, but the assumption moves the total more than any rate change. On Railway the same consolidation barely matters, because metered volumes cost ~$0.03/project either way. If your projects can share a database, re-run the floor rows before believing them; if each needs isolation, the 1:1 unit stands.

Two crossovers, not one​

The table's raw-dollar crossovers (N=1 for floors, N≈2–4 for meters) answer a question nobody should act on, because they price the box as free labor. The crossover worth migrating on loads the box with its real cost: rental + management-plane equivalent + your time. Stated explicitly: value ops time at $50–100/hour, budget ~1 hour a month of box care (patching, monitoring, TLS, the occasional 2am disk), and count the Cluster API management plane as roughly one more small box (~$7–19/month equivalent). Loaded Box A lands around $65–125/month depending on how you value your own evenings.

Against that loaded number, the crossovers move:

  • Railway metered (~$2.16/project) crosses the loaded box at N≈30–60, bracketing the guide's own "past 30–50, self-hosting starts paying for the time it costs." The range is the honest answer: at $50/hour it is ~30, at $100/hour it is ~60.
  • Render's floor ($13/project) crosses the same loaded box at N≈5–10. Even fully loaded with generous ops math, fixed-floor pricing loses early — the floor multiplies too fast for any plausible time valuation to rescue it.
  • Fly.io metered sits between the two depending on how much autostop saves you off the always-on ceiling; model your idle ratio before trusting either endpoint.

This is the half of the analysis a single-project benchmark can never show. Benchmarks compare one service's rate cards, where a $13 floor looks reasonable next to $2 of metered usage. Sprawl compares the slope: floors multiply by project count with no idle discount, meters multiply by resources actually held, and the box stays stepped-flat until the capacity cliff. The shape of your portfolio — how many, how idle — picks the winner more than any vendor's rate.

One honest note on the "under Cluster API" qualifier: at single-box scale, a full CAPI management cluster is overkill — its management plane costs about as much as the box it manages, which is precisely why the burden-adjusted crossover sits at 30–60 and not 3–4. CAPI earns its place at box #2, where it keeps the curve stepped-flat instead of forcing a replatform: same deploy UX, split blast radius, one more $7–19 box. Price the fleet layer from the start so the crossover you migrate on survives growing past it.

What moves the crossover​

Three variables move every number above more than any rate tweak.

Busy beats idle, and flips the winner. The whole metered advantage assumes projects sit quiet. A project burning a full vCPU around the clock costs ~$20 in CPU alone on Railway before RAM — already past Render's $13 floor. Somewhere between "dormant toy" and "always-busy service" the lines cross and fixed pricing wins; if your portfolio skews busy, invert this post's conclusion and re-run the table at your utilization, because the floor's flatness becomes a discount instead of a tax.

The box column drifts too. Self-hosting is not a fixed price, and 2026 proved it: Hetzner's June 15 price adjustment raised cloud plans across the board (the CX23 went €3.99 → €5.49, dedicated-CPU lines roughly tripled, and the AX42-class dedicated box now lists at €97.30/month), while the cheapest SKUs flicker in and out of availability — the guide found the CX23 marked "not available" in late August. This post pins Box A to the CX23/CAX11 class (~$7) with the ARM-based CAX11 as the available substitute at the same tier, but treat any box price as a snapshot: re-check the price list before budgeting, the same way you would a hosted vendor's.

One box is one blast radius. Every project on Box A shares its fate: a bad kernel update, a full disk, or a provider outage takes down all N at once, where hosted platforms isolate failures per service. That concentration is the real price of the flat curve, and the mitigations (backups you test, a standby box, splitting stateful services off) all add back cost or complexity. Count the risk mitigation in the loaded comparison, not after it.

Which meter for your portfolio​

The decision collapses to the guide's two questions: how many projects do you actually run, and what is your ops time worth. Under ~10 tiny projects, stay on a usage meter — Railway or Fly.io with a self-hosted database lands in the same $15–30/month band as the anchor, with someone else holding the pager. One or two projects that genuinely matter (revenue, real users, data you would grieve) earn a fixed floor for managed backups and support, even while the rest of the portfolio sits on the cheaper meter — nothing says all N projects must live on one platform. Past 30–50, the floor-times-N multiplication stops being a rounding error and the flat box starts paying for your time; at N=100, ~$220 metered versus ~$35 on a box is the difference between a forgotten subscription and a line item that needs explaining.

The through-line is that someone always operates the machine, and sprawl decides how that cost scales: per project, per gigabyte held, or per box. A self-hosted PaaS on hardware you own — flat-rate machines, declarative fleet management, git-push deploys on top — is the attempt to hold the per-box curve while automating the pager-duty row down to something one developer can carry.

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

Check your move before you migrate

Free browser tools: check a render.yaml or your Render scripts against bex, or turn a Heroku app or docker-compose.yml into a draft render.yaml. Nothing you paste leaves your browser.

Open the migration tools