On October 7, 2024, Fly.io deleted its own pricing menu. No more Hobby at $5, no more Launch at $29, no more Scale at $199 — replaced with a single line: pay for what you use, billed per second, from the first second. A shared-cpu-1x/256MB machine at $2.02 a month or a 512MB one at $3.32 looked like the cheapest possible deal for an always-on app. Then January 1, 2026 arrived, and two new billing lines turned on — volume snapshots and app-scoped egress IPs — on top of volumes, egress, and dedicated IPs that were already metered.
So what does the same always-on app actually cost once every line is counted — and what does it cost on a flat-rate box where no vendor can add a line item unilaterally?
Here is the answer in one table. The workload is fixed — a web service (512MB), a background worker (512MB), a scheduler (256MB), all always-on (730 hours), 20GB of persistent volumes, 100GB of NA/EU egress, one dedicated IPv4, daily volume snapshots retained 30 days — priced at Fly.io's documented 2026 rate card versus the same workload bin-packed onto a single Hetzner CX23 (2 vCPU / 4GB / 40GB, ~€5.49/mo post-June-2026, 20TB bandwidth included).
| Platform | How the invoice adds up | Monthly total |
|---|---|---|
| Fly.io (always-on, NA/EU) | Compute $8.66 + volumes $3.00 + egress $2.00 + IPv4 $2.00 + egress IP $3.60 + snapshots ~$3.00 | ~$22.26 |
| Hetzner CX23 (flat, EU) | 1 box €5.49 (~$5.93) — egress $0, snapshots $0, IPs included | ~$5.93 flat |
| Delta | Fly.io meter-everything vs one flat box | ~3.8x — Fly.io costs ~$16 more |
Add a second Hetzner box for HA and Fly.io is still ~1.9x more. Move that 100GB of egress to Africa/India at $0.12/GB and the gap widens to ~5x. The rest of this post shows every line of that math, where the 2024 plan deprecation actually landed, every billing dimension Fly.io now meters, and the harder question pure usage-based pricing raises: can you reason about next month's invoice before it arrives, or only after?
What Fly.io actually killed on October 7, 2024
Before that date, Fly.io sold plans the way most PaaS do — a subscription that bundled usage:
| Legacy plan | Monthly fee | What it included |
|---|---|---|
| Hobby | $5/mo | $5 of usage credit + support |
| Launch | $29/mo | $29 of usage included |
| Scale | $199/mo | Larger included usage + org features |
After October 7, 2024, there is no plan. New organizations get pay-as-you-go from the first machine-hour, with only a one-time trial — roughly 2 machine-hours or 7 days, whichever ends first — and then every second is billable. Legacy organizations that existed before the cutoff keep their old allowances as a grandfathered benefit, but new signups have no free tier for anything that needs to stay running.
The deprecated page at fly.io/docs/about/pricing/#discontinued-plans says it plainly: "Fly.io no longer offers plans to new customers. If you purchased a Launch or Scale plan before October 7, 2024, you can remain on those plans."
Why "same price, fewer tiers" is wrong: the sticker price per vCPU-second did not need to rise for the bill to rise. Removing the plan removed the only ceiling that turned usage into a flat number. A $5 Hobby credit that previously absorbed a small always-on app's compute now does not exist for new teams — the same workload that previously rounded to $5 now invoices at its metered total, whatever that total turns out to be that month. As the June 2026 audit "Your PaaS Bill Lied to You" noted, Heroku in maintenance mode, Vercel on its fourth repricing, and Fly.io on new billing lines are all narrowing included usage — each narrowing is a bill increase that never touched the compute rate card.
Every billing line that now counts for an always-on app (2026 rate card)
Pure usage-based pricing sounds simple — "you only pay for what you use" — until you list what counts as "use." For an always-on app that never sleeps, Fly.io meters at least six dimensions, each billed independently:
| Billing line | Rate (2026 documented) | Notes |
|---|---|---|
| Compute — shared-cpu-1x | 256MB $0.0028/hr → $2.02/mo · 512MB $0.0046/hr → $3.32/mo · 1GB ~$5.92/mo | Per-second, 730 hours if always-on. RAM scales ~$5/GB/mo on shared cores. |
| Volumes | $0.15/GB/mo, pro-rated hourly | Billed whether the machine is running or stopped. A forgotten 3GB volume in fra still invoices. |
| Volume snapshots | Billable since Jan 1, 2026 | Daily automatic snapshots, retention 1–60 days. First charges appeared on February 2026 invoices. |
| Egress | $0.02/GB NA/EU · $0.04/GB APAC/Oceania/SA · $0.12/GB Africa/India | The 6x regional spread is the single biggest swing in the bill. |
| Dedicated IPv4 | $2.00/mo per IP | Required for external access via fly ips allocate. IPv6 is not billed the same way. |
| App-scoped egress IPs | $3.60/mo per IPv4, billed hourly | Beta in late 2025, billable since Jan 1, 2026. One per app if you need stable outbound IPs. |
| Stopped-machine rootfs | $0.15/GB/mo | Even stopped machines bill for their root filesystem. |
| GPU Machines | Deprecated, unavailable after Aug 1, 2026 | Not in the always-on comparison, but a line that was removed rather than added. |
Two lines that surprised teams in early 2026 were snapshots and egress IPs — both announced in December 2025 with a "billing starts January 1" notice and both invisible to anyone who had priced Fly.io off a 2024 blog post. A single 20GB volume with 30 days of daily snapshots retained at ~$0.15/GB-equivalent adds roughly $3/mo that did not exist in 2024. One app-scoped egress IPv4 adds $3.60/mo whether the app sent a byte or not.
Worked model: the same app, priced both ways
Fix the workload — never let the platform move the goalposts — then price it line by line. The reference app is a boring, representative SaaS shape, not a toy and not a strawman:
- Web: shared-cpu-1x / 512MB, always-on, serves HTTP
- Worker: shared-cpu-1x / 512MB, always-on, drains a job queue
- Scheduler: shared-cpu-1x / 256MB, always-on, runs cron
- Storage: 20GB persistent volume (10GB app data + 10GB Postgres)
- Egress: 100GB outbound to NA/EU (CDN + API responses)
- Networking: 1 dedicated IPv4 + 1 app-scoped egress IP
- Backups: Daily volume snapshots, 30-day retention
- Uptime: 730 hours/month, no scale-to-zero, no sleep
Fly.io — every line summed
| Line | Calculation | Monthly |
|---|---|---|
| Web (512MB) | $3.32 | $3.32 |
| Worker (512MB) | $3.32 | $3.32 |
| Scheduler (256MB) | $2.02 | $2.02 |
| Compute subtotal | $8.66 | |
| Volumes (20GB × $0.15) | 20 × 0.15 | $3.00 |
| Snapshots (~20GB × 30-day weighted retention) | ~$3.00 (varies by retention) | ~$3.00 |
| Egress (100GB × $0.02 NA/EU) | 100 × 0.02 | $2.00 |
| Dedicated IPv4 | 1 × $2.00 | $2.00 |
| App-scoped egress IP | 1 × $3.60 | $3.60 |
| Fly.io total | ~$22.26/mo |
Rounded conservatively. At the documented per-second rates, a month is not "about 730 hours" — it is 730 hours for an always-on machine — so the compute lines are exact. The snapshot line is the only estimate with real variance: Fly.io bills snapshots by GB-month of retained snapshot storage, so a 20GB volume with high churn snapshots retains more than 20GB of diffs; a mostly-static volume retains close to 20GB. We use ~$3 as a representative middle.
One line that does not appear: ingress. Fly.io does not meter inbound bandwidth, so the request path in is free — only responses out incur egress.
Hetzner — the same workload on one flat box
| Line | Cost |
|---|---|
| CX23 (2 vCPU / 4GB / 40GB NVMe) | €5.49/mo (~$5.93) — post-June-15-2026 price, EU region |
| Volumes | $0 — NVMe is the box. Need more, add a Volume at ~€0.05/GB/mo, still flat |
| Egress (100GB) | $0 — 20TB included per CX23 in EU/US. 100GB is 0.5% of the allotment |
| Snapshots/backups | $0 under bex's own backup tooling on the same disks; Hetzner Backups ~20% of box price, still flat |
| IPs | Included — one IPv4 + /64 IPv6 per server, no per-IP meter |
| Hetzner total | ~$5.93 flat |
The 40GB NVMe on the CX23 already holds the 20GB the reference app needs, so no extra volume is required. Two CX23s for high availability double the flat cost to ~$11.86/mo — still ~46% cheaper than Fly.io's single-region metered total, and both boxes still carry 20TB each.
The delta: ~$16.33/mo, or ~3.8x. For a single app it is the price of lunch. At 10 identical tenant apps — the shape a small PaaS fleet actually holds — the meter-everything model multiplies to $222/mo in metered lines while the flat model multiplies only in boxes ($59/mo for 10 tenants bin-packed onto 3 CX23s with headroom), widening the gap from additive to structural.
Sensitivity: how the delta moves
A single worked example can flatter either side if the inputs are cherry-picked. Show the range, not one point:
| What changes | Fly.io total | Hetzner total | Delta |
|---|---|---|---|
| Base case above (6GB total RAM, 20GB vol, 100GB NA/EU egress) | ~$22.26 | ~$5.93 | 3.8x |
| +4GB RAM (web/worker to 1GB each) | ~$32.10 (extra ~$9.84 at ~$5/GB) | ~3.7–5.4x | |
| 100GB egress to Africa/India ($0.12/GB) | ~$32.26 (egress $12, not $2) | ~$5.93 (still inside 20TB) | ~5.4x |
| 100GB volume instead of 20GB | ~$37.26 (vol $15 + snapshots ~$11) | ~$5.93 + one 80GB volume | ~3.6x |
| 500GB egress, NA/EU | ~$30.26 (egress $10) | ~$5.93 | ~5.1x |
| 500GB egress, Africa/India | ~$70.26 (egress $60) | ~$5.93 | ~11.8x |
Three things stand out:
-
Egress geography dominates. The 6x spread between NA/EU ($0.02) and Africa/India ($0.12) is larger than any compute difference. A team serving a global audience on Fly.io pays a different bill depending on where its users happen to be that month — something a bandwidth-included Hetzner box never exposes.
-
RAM is the second lever. Fly.io's ~$5/GB/mo adds up linearly and never amortizes. On Hetzner, RAM is bundled — moving from a 4GB CX23 to an 8GB CPX22 is one flat step, not a per-GB meter.
-
Volume size compresses the gap slightly, egress widens it. Bigger volumes cost both sides, but Hetzner volumes stay flat while Fly.io adds both volume and snapshot lines. Bigger egress costs only Fly.io — Hetzner stays at $0 until you exhaust 20TB, which the reference app never approaches.
The forecasting problem pure usage-based pricing creates
The hardest cost of usage-based pricing is not the number on the invoice — it is not knowing that number until the invoice arrives.
On a flat Hetzner box, next month's compute bill is known on day one: €5.49, whether the app serves 10 requests or 10 million, whether egress is 10GB or 10TB, whether snapshots were retained 7 days or 60. The only variable is whether you add or remove a box — a deliberate, declarative decision you make, not one a meter makes for you.
On Fly.io's pure usage model, the invoice is the sum of six independent meters that each move with usage you do not perfectly control:
- Egress moves with user geography. A feature that goes viral in a $0.12/GB region costs 6x the same bytes in NA/EU, and you learn which region after the fact.
- Snapshots move with write churn. A busy write day produces larger diffs; a quiet day produces smaller ones. The retention window you chose weeks ago determines how much history is still billing today.
- Volumes never sleep. A volume you created for a one-off experiment in
frabills at $0.15/GB/mo until you delete it — and Fly.io reminds you in its own docs: "Volumes don't stop billing when your machines do." - Egress IPs bill per hour whether the app sent a packet or not. Forgetting to release one after a migration is a silent $3.60/mo line that the cost explorer surfaces only when you go looking.
- Per-second compute is the honest part — but only if you actually scale to zero. An always-on app by definition does not, so per-second billing is just a more precise way to say "730 hours at the hourly rate."
The operational consequence is a forecasting tax. A team that budgets quarterly must either estimate each meter's movement — guessing at egress geography and snapshot churn — or wait for Fly.io's cost explorer and invoice preview to tell them what already happened. The June 2026 audit put it bluntly: every platform that narrows included usage without touching the compute rate has still raised the price — it just moved the increase into a dimension the buyer was not watching. Two new billing lines on January 1 is exactly that kind of move.
A flat box does not solve this by being cheaper on every workload — it solves it by being knowable. The invoice on day one is the invoice on day thirty. That predictability is worth more than the raw delta for any team that has to answer "what will next month cost if traffic doubles?" before the month starts, not after.
When Fly.io still wins — and what to measure before you migrate
Usage-based pricing is not a mistake — it is a pricing shape, and shapes have workloads they fit. Fly.io wins cleanly where Hetzner flat pricing loses:
- Burst and scale-to-zero. An API that handles 10k requests at 9am and zero at 3am, with
auto_stop_machines = true, bills for minutes — not 730 hours. A flat box bills the same 730 hours regardless. Per-second shines when average utilization is far below peak. - Global Anycast without operating regions. Fly.io's Anycast edge and
fly deploy --regionare a single command; Hetzner requires you to wire regions yourself, even with Cluster API. - Ephemeral workloads. Preview environments, CI runners, one-off data jobs — anything whose lifetime is hours, not months — are cheaper billed by the second than by the month.
What to measure before you decide:
- Average vs peak utilization. If your three services average 15% CPU and you could scale to zero overnight, collect a week of per-minute utilization — usage-based may be cheaper than flat. If they sit at 40%+ and never sleep, the flat box wins.
- Egress geography. Pull last month's egress by region from your current provider. If >20% leaves toward APAC/SA/Africa, price that slice at $0.04–$0.12, not the $0.02 headline.
- Volume and snapshot churn. Snapshot cost tracks write churn, not provisioned size. A 20GB Postgres that rewrites heavily snapshots larger than a 20GB static-asset volume — measure diff size, not just volume size.
- IP and ancillary lines. Count every dedicated IPv4 and egress IP you actually hold. On Fly.io they are $2 and $3.60 each, every month, independent of traffic.
If the answer across those four is "always-on, mostly NA/EU, moderate volumes, predictable traffic" — the reference app's shape — the line-by-line math above is close to your bill, and the flat Hetzner box is predictably cheaper. If the answer is "bursty, ephemeral, global, scales to zero" — Fly.io's meter is the better fit, and a self-hosted fleet would waste capacity waiting for the next burst.
Either way, price the workload you actually run, with the billing lines that actually invoice — not the ones that existed when the blog post you read was written.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Flat, knowable pricing on Hetzner hardware under Cluster API, with no per-second meter, no per-GB egress surprise, and no new billing line a vendor can add unilaterally. Star the repo on GitHub or deploy your first app today.