Skip to main content

That $3,000-to-$200 Kubernetes-to-Fly.io Migration Story, Audited Line by Line

9 min readDora NodaDora Noda
Share
On this page

Every few months, a new entry joins my favorite cloud-cost genre: the reverse-migration receipt. A team posts two numbers — a roughly $3,000/month managed Kubernetes bill and a roughly $200/month Fly.io bill for the same workload — and the internet nods along. Fifteen times cheaper, four-minute deploys, no YAML. What is there to argue with?

Plenty, as it turns out — not because the story is fake, but because both numbers are doing quiet work the headline never shows. I took the claim at face value and audited each side against the vendors' own September 2026 price lists. The migration is real. The 15x is doing a lot of heavy lifting.

The claim, stated fairly​

Before auditing anything, steelman the story. A $3,000 managed-Kubernetes bill is not mysterious; it decomposes into familiar parts. A typical small-production setup on a hyperscaler looks roughly like this:

  • Managed control plane: about $73/month per cluster (EKS-style $0.10/hour pricing), times two for staging and production — call it $150.
  • Worker nodes: a half-dozen general-purpose instances running 24/7 whether anything is busy or not — roughly $1,850.
  • Persistent disks: a few hundred GB of provisioned SSD — about $180.
  • Load balancers and NAT: fixed hourly charges plus data-processing fees — around $120.
  • Egress: a terabyte or two at cloud bandwidth rates — say $250.
  • Observability and support: hosted metrics/logging plus a percentage-of-spend support plan — roughly $450.

Total: just about $3,000. No single line of that bill is outrageous. The villain is structural: fixed capacity billed around the clock, plus percentage-based add-ons that scale with the waste. This genre is popular because the pattern is real — one widely shared 2026 writeup moved a $47,000/month Kubernetes setup to Fly.io for about $3,200 with the same performance, and the mechanism was identical: stop paying for idle.

So the "before" number survives contact with reality. Now the "after" number.

The audit table​

Here is the core artifact: the $200 Fly.io bill reconstructed from Fly.io's current published price list, next to what each row replaces — and what the headline omits.

Line itemOld bill (managed K8s)Fly.io replacementOmitted by the story
App tier (3 instances)part of $1,850 nodes3× shared-cpu-2x/2 GB ≈ $36Regional markup: same machines cost 1.21x in Frankfurt, 2x in Singapore or Tokyo, 3x in Mumbai
API tier (dedicated)part of $1,850 nodesperformance 2 vCPU/4 GB with autostop ≈ $16At 100% duty cycle this machine is $65 — the $16 assumes it sleeps ~75% of the time
Background workerspart of $1,850 nodes2× shared-cpu-1x/1 GB ≈ $12Stopped machines still bill for attached volumes
PostgresRDS-style managed instance ≈ $200+Single self-managed node ≈ $33Fly Postgres is unmanaged; the 3-node production preset runs $82–164, and failover is yours to operate
Persistent disks$180 provisioned SSD100 GB × $0.15 ≈ $15—
Snapshots/backupsfolded into managed storage—Volume snapshots billed since Jan 1, 2026 at $0.08/GB-mo (first 10 GB free); auto daily snapshots with 5-day retention are on by default
Egress (~500 GB)$250~500 GB × $0.02 ≈ $10Rate triples to $0.04 in APAC/South America and hits $0.12/GB for Africa/India; cross-region private traffic bills too ($0.006–0.05/GB)
Second regionextra nodes, LB, NAT ≈ $400+replica machines ≈ $40Cross-region markup stacks with the regional compute markup above
Redismanaged cache ≈ $60Upstash via Fly extensions ≈ $20Third-party list prices, metered separately on the same invoice
IPs, certs, miscfolded into LB/NATshared IPv4 free, certs $0.10/host ≈ $5Dedicated IPv4 is $2/mo each; static egress IPs ≈ $3.60/mo each
Support~10%-of-spend plan ≈ $270community/freeFly Standard support is $29/mo — cheap, but it is not $0
Control plane$150$0 — there is no clusterFly's own managed Kubernetes (FKS) costs $75/mo per cluster, if you ever want the abstraction back
Totals≈ $3,000≈ $187 (call it $200)$100–300/mo in conditional rows

The headline survives the audit in the narrow sense: yes, roughly $200 buys roughly the same serving capacity — for a bursty workload in a cheap region with a single database node, no support plan, and machines that sleep most of the day. Every italicized qualifier is a row in the right-hand column. None of them is hidden; all of them are on the public pricing page. They just never fit in the headline.

What the headline figure leaves out​

Three of the omitted rows deserve more than a table cell.

Snapshots are a 2026 meter. Volume snapshot storage started billing on January 1, 2026, at $0.08/GB-month with the first 10 GB free. Automatic daily snapshots with five-day retention ship enabled by default on new volumes. For a small database this is a few dollars. For a few hundred GB of retained snapshots it is a new $15–25/month line that did not exist when the earliest "$200" screenshots were taken. Early-2026 meter expansions are exactly the kind of drift that makes last year's receipt wrong this year.

Regions are a multiplier, not a footnote. Fly.io publishes per-region compute markups: 1.0x in Amsterdam and Ashburn, 1.21x across most of the US and Europe, 2x in Singapore, Sydney, and Tokyo, 3x in Mumbai and Johannesburg. A topology that costs $200 in Ashburn costs about $240 in Frankfurt and $400 in Singapore for identical machines. Egress follows the same geography: $0.02/GB in North America and Europe, $0.04 across Asia-Pacific, Oceania, and South America, $0.12 for Africa and India. Any migration story that does not name its regions is quoting the cheapest row of the table as the total.

The $16 dedicated VM is a duty-cycle claim. A performance 2 vCPU/4 GB machine bills about $65/month running around the clock at the 1.0x markup. Landing at $16 means autostop/autostart is doing its job and the machine is stopped roughly three-quarters of the time. That is a genuine platform feature and exactly right for bursty workloads. It is also the opposite of a production API with steady traffic, where the same row costs 4x the quoted figure. The story's cheapest numbers all share this shape: they price the platform's best behavior, not its average behavior.

The 10x sensitivity check​

The deepest question about any migration receipt is not whether the numbers add up today but which rows bend when traffic grows 10x. Running the same topology at ten times the traffic:

Line itemAt 1x trafficAt 10x trafficScaling shape
Fly.io compute~$100~$400–600 (more, bigger, or more-awake machines)Sub-linear if bin-packed well, linear if just replicated
Fly.io egress (NA/EU)~$10~$100 (5 TB × $0.02)Linear, forever
Fly.io egress (APAC-heavy)~$20~$200+Linear at 2–6x the NA/EU rate
Snapshots, IPs, support~$30~$50Mostly flat
Fly.io total~$200~$550–850—
Old managed-K8s bill~$3,000~$3,500–4,500 (mostly headroom absorbing it)Step function: flat until the next node

This is the honest version of the story. At 1x, Fly.io wins 15-to-1 because the old bill is dominated by idle capacity. At 10x, the old bill barely moves — that idle capacity was headroom all along — while the metered bill climbs linearly, led by egress. Somewhere past 10x the lines cross for bandwidth-heavy workloads, and they never cross for spiky, idle-mostly workloads. "15x cheaper" was never a property of the platform. It is a property of one workload shape at one traffic level.

The row neither side prices: owned hardware​

Both sides of the story share one blind spot: a flat monthly server. The same topology — app tier, API, workers, Postgres with replicas, Redis — fits comfortably on a single Hetzner AX42-class dedicated box (8 cores/16 threads, 64 GB RAM) at roughly €47–67/month post-2026 pricing, with unmetered traffic on a gigabit uplink. A high-availability pair lands around €130/month. At roughly €1 ≈ $1, the owned-hardware row reads ~$65 single, ~$130 HA, and it does not move at 10x traffic until the hardware itself saturates.

The honest caveat, stated plainly: the owned row buys no one to page. Somebody provisions the machine, runs the upgrades, and owns Postgres failover at 3 a.m. The migration story's real comparison was never $3,000 vs $200 — it was managed waste vs metered precision vs owned flat-rate plus your own labor. Price all three rows before picking, and weight them by how your team actually spends nights and weekends.

Verdict: what the story proves and what it doesn't​

It proves: managed-Kubernetes overhead is the dominant term in small-fleet cloud bills. Control-plane fees, 24/7 nodes sized for peak, percentage-of-spend support, and cloud egress compound into a $3,000 floor that has little to do with serving traffic. Right-sizing beats re-platforming as an explanation — the win comes mostly from paying for used capacity instead of reserved headroom, and any platform with scale-to-zero would capture most of it.

It doesn't prove: that Fly.io is 15x cheaper as a general fact. The $200 figure assumes cheap regions, sleeping machines, a single database node, no support plan, and pre-2026 snapshot habits. Change any two of those and the ratio halves. Change the workload shape to steady-state and always-on, and the metered bill starts climbing toward the very number it replaced — while the owned-hardware row sits flat underneath both.

Migration receipts are still worth reading. Just read them the way you would read any benchmark: reproduce the topology, check the date on every meter, name the regions, and ask what the next order of magnitude costs. The platforms publish all of it. The headline just can't hold it.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. If this audit has you pricing the owned-hardware row seriously, 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