Fly.io didn't raise its price in January 2026. It added a new thing to charge for. Then in February, it added another.
One changelog said volume snapshots — free since the feature launched — would be metered at $0.08/GB-month starting January 1. A second said inter-region private networking for Managed Postgres would be billed at existing private-network rates starting in February. Same per-second Machines. Same $0.15/GB volumes. Same $0.02/GB egress in North America and Europe. Just — two more lines on the invoice that were $0.00 the month before.
That's a different risk than a price hike. A hike changes a number you already track. Metering creep changes how many numbers you track — and a vendor that bills by the second can add a new one any quarter.
TL;DR — One workload, two new lines, one flat alternative
| Line | Before Jan 2026 | After Feb 2026 | Delta |
|---|---|---|---|
| Compute — 2× shared-cpu-1x 512MB, 24/7 | $7.60 | $7.60 | — |
| Volumes — 2× 20GB at $0.15/GB | $6.00 | $6.00 | — |
| Egress — 100GB to NA/EU at $0.02/GB | $2.00 | $2.00 | — |
| Volume snapshots — incremental, 5-day retention, first 10GB free | $0.00 | $0.80 – $3.20 | new |
| MPG inter-region private networking — same rate as private network, intra-region free | $0.00 | $0.60 – $2.40 | new |
| Total | $15.60 | $17.00 – $21.20 | +9% to +36% |
| Same workload on Hetzner CX23 (2 vCPU, 4GB, 40GB, 20TB included) | $6.73 flat | $6.73 flat | no new dimension |
The range is retention and replication volume. A quiet 16GB of used blocks barely registers. A realistic 40GB database plus 30–50GB of cross-region replication adds a quarter to the bill. Move that 100GB of egress to Africa or India ($0.12/GB vs. $0.02) and Fly totals $25 before the new lines, while the Hetzner box is still $6.73 with 20TB included.
The point isn't "Fly gouged anyone." It's that a per-dimension meter makes your forecast depend on how many dimensions exist — and that count went up twice in 60 days.
What actually changed
Fly's two additions are often collapsed into "they charge for more stuff." They are distinct meters with distinct triggers.
January 1 — volume snapshot storage
- Before: Every volume gets an automatic daily snapshot (5-day retention by default, 1–60 days configurable). Storage was free through December 31, 2025.
- After: Total stored snapshot size is billed at $0.08/GB per month, first 10GB free per org, pro-rated hourly, first charged on the February invoice. Stored size is measured at the block-device level, not
df— writing 1GB to a 10GB volume bills ~1GB. Snapshots are incremental (only changed blocks consume new storage), compressed and deduplicated. Encrypted volumes don't compress, so billed size tracks allocated blocks more closely. - Who is untouched: Fly notes 98% of customers see no charge and, of the remaining 2%, 83% see under a 10% increase. The 10GB free covers small projects; it doesn't cover a database that churns daily.
February — inter-region private networking for Managed Postgres
- Before: Private-network traffic between Machines over Fly's 6PN (WireGuard/Flycast) was pooled in a free quota.
- After: For Managed Postgres (MPG), traffic that crosses regions on the private network is billed at the same rate as existing private-network usage, sharing the same free quota. Intra-region stays free. A zero-price preview line appeared in December 2025 invoices; live billing hit March invoices for February usage.
- Trigger: Primary in
frawith a replica iniad, or apps in two regions querying one Postgres — Fly's own multi-region pattern. Every byte of cross-region replication and cross-region queries becomes billable.
Two lines, two independent triggers. One activates when you rely on daily backups (enabled by default). The other activates when you run Postgres the way Fly's guides recommend.
The representative workload
To avoid theater, the comparison uses the team that followed Fly's happy path — not an idle single-machine hobby app, not a 64GB dedicated server.
- 2× Machines,
shared-cpu-1x512MB, one iniad, one infra, behind Fly Anycast, running 24/7. - 1× Managed Postgres primary in
frawith a read replica iniad. Two 20GB volumes, 8GB written per volume in the quiet case, 20GB in the busy case. Daily snapshots, 5-day retention. - 100GB/month egress to mixed NA/EU, with sensitivity checks at 500GB and at Africa/India egress rates ($0.12/GB).
- MPG replication/query traffic: 30GB/month (light) and 120GB/month (write-heavy) cross-region.
A single 256MB machine with no volumes and no MPG would skip both new lines entirely. That's not the bill that changed.
Line by line: the invoice before and after
At January 2026 list pricing — per-second Machines, $0.15/GB volumes hourly, $0.02/GB egress in NA/EU, incremental snapshots, intra-region private free:
| Line item | Calculation | Monthly cost |
|---|---|---|
| Compute | 2× shared-cpu-1x 512MB ≈ $0.0052/hr × 730h | $7.60 |
| Volumes | 2× 20GB × $0.15/GB | $6.00 |
| Egress | 100GB × $0.02 | $2.00 |
| Subtotal before new lines | $15.60 | |
| Snapshots — quiet | 16GB used → ~20GB stored over 5 days, minus 10GB free = 10GB × $0.08 | +$0.80 |
| Snapshots — busy | 40GB used → ~55GB stored, minus 10GB free = 45GB × $0.08 | +$3.20 |
| MPG private — light | 30GB cross-region × ≈$0.02 | +$0.60 |
| MPG private — heavy | 120GB × ≈$0.02 (higher in APAC/Africa) | +$2.40 |
| Total — quiet | $15.60 + $0.80 + $0.60 | $17.00 (+9%) |
| Total — busy, NA/EU | $15.60 + $3.20 + $2.40 | $21.20 (+36%) |
| Busy + 500GB egress | +$10.00 egress instead of $2.00 | $29.20 |
| Busy via Africa/India | Egress 100GB × $0.12 = $12.00 | $31.20 |
Three details the average hides:
- Snapshot size ≠ provisioned size, but churn drives storage. A 20GB volume with 3GB used bills ~3GB. An 80GB Postgres that actually uses 50GB bills ~50GB even after deduplication, and daily churn multiplies incremental copies. Encrypted volumes don't compress, so they track provisioned occupancy more closely.
- Retention is price. Dropping from 5 days to 1 day on a high-churn volume can halve stored size. Stretching to 60 days on a write-heavy Postgres grows it near-linearly. A reliability preference just became a billing knob.
- Inter-region is free until you do the recommended architecture. Two apps in
fratalking to Postgres infraremain $0. The bill appears exactly when you put the app near users in two regions — the architecture where Fly is supposed to win on latency versus a single-region box.
The same workload on a flat Hetzner box
Put the same app and database on owned Hetzner hardware under Cluster API (the path Bex.co automates, but the math holds for any direct tenancy).
One-machine equivalent: Hetzner CX23 — 2 vCPU, 4GB RAM, 40GB NVMe, 20TB included — is €5.49/month excluding VAT (about $6.73) on post–June 15, 2026 pricing. A step up, CX33 (4 vCPU, 8GB, 80GB), is roughly €12–€14. Volumes are local NVMe; no separate volume-hours meter. Snapshots are filesystem or restic/borg to a second box or object storage — no $0.08/GB month.
| Fly.io driver | Fly.io 2026 | Hetzner CX23 at $6.73/mo |
|---|---|---|
| Bandwidth headroom | Per-GB charged | 20TB included — 200× the 100GB workload |
| Extra snapshot retention | More $0.08/GB | Local snapshot or adjacent backup host — storage only |
| Second region | New private-network line | Second box — second flat price, not a traffic meter |
| Vendor adds a meter | Invoice gains a line | Impossible — no dimension to add; you add a box |
Honest footnote: Hetzner also moved in 2026. CCX dedicated lines jumped roughly 2.1–2.75× and CPX shared AMD lines 2.4–2.75× in Germany/Finland on top of a ~37% April hike, while CX/CAX rose a modest ~30%. The lesson isn't "Hetzner is always cheapest" — it's that Hetzner raised one number per family. It didn't invent a new class of resource. Forecasting stayed one-dimensional: compare families and pick CX/CAX if you don't need dedicated cores. Quoting CCX as the entry point is quoting a price that no longer exists; tracking a meter you didn't know existed is harder than looking up a revised card.
Why creep is not "just a price hike"
Usage-based PaaS pricing moves in three ways, and only one shows up in "my bill went up X%" retellings:
-
A price moves — $0.15/GB becomes $0.18/GB. Multiply last month's usage by the new rate.
-
Included usage narrows — Render cut Hobby egress 100GB → 5GB (Pro 100GB → 25GB) at $0.15/GB overage in April 2026 and shifted per-seat to per-workspace. Vercel repriced four times since 2024, narrowing bandwidth, functions, and storage under the same $20 Pro while collapsing 20+ limits into a $20 credit pool. Same usage, smaller inclusion.
-
A dimension is added — previously unmetered resources get a rate and free tier. Fly snapshots ($0.08/GB, 10GB free) and MPG inter-region networking (same rate, same quota) are textbook class-3 moves. Cloudflare's January 2026 Durable Objects storage and August 2026 Workflows per-step billing are the same genus.
Class 1 is forecastable from last month's invoice. Classes 2 and 3 require forecasting a resource you weren't measuring — or a limit you didn't know would shrink. Each new dimension brings its own rate, geography (Fly egress is $0.02 in NA/EU, $0.04 in APAC, $0.12 in Africa/India), free tier, and behavioral coupling (retention, topology). Fly shipped both well — 60–90 days notice, zero-price preview lines, docs pointing at fly volume snapshots list — but good hygiene doesn't change the structure: a metered vendor can add a dimension; a box you own cannot.
Every PaaS on this list has let creep in at a different seam — Fly in snapshots and private networking, Render in egress, Vercel in Active CPU, Cloudflare in steps and storage. The shape is the same: more lines, not just bigger numbers. A self-hosted PaaS removes that shape, not by being cheaper on day one, but by making "a new thing to meter" impossible. The platform vendor and the hardware vendor are not separate roadmaps that can re-meter each other.
What to do if you run on Fly.io today
You don't have to migrate to make these meters boring:
-
Audit retention.
fly volume snapshots list <volume-id>shows stored size per snapshot. For cache or artifact volumes where you already ship backups to R2/B2, disable automatic snapshots and rely on external backups. For production Postgres, keep snapshots but drop from 5 days to 1–2 if you already runpg_basebackupor WAL archiving. -
Co-locate Postgres with its hottest querier. If 80% of queries originate in
fra, run the primary there and avoid hot-path cross-region queries. The February meter only counts cross-region bytes. -
Push egress-heavy assets to zero-egress storage. Thumbnails, release artifacts, and video segments at $0.02–$0.12/GB belong on R2 (zero egress) or B2 if you can tolerate the integration. This dwarfs any snapshot tuning beyond 500GB.
-
Price the flat alternative once. A Hetzner CX23/CX33 per location under Cluster API, plus
resticto a second box or R2, covers this workload at one price per location. The setup cost is one-time; the invoicing cost is predictable. The question creep forces is not "which is cheaper at 100GB this month" but "which lets me predict next quarter without reading another changelog?"
The cheapest invoice in a single month is rarely the point. The predictable one is. Fly.io's two lines are small, well-signaled, easy to tune — and still a quarterly reminder that a metered PaaS can re-meter, while a box you own can only get more or less expensive as a box. In a year when DRAM-driven hardware hikes already made "own cheap hardware" three different prices depending on which Hetzner line you picked, that difference is worth more than any line-item comparison.
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.