Skip to main content

Fly.io's $0.08/GB Snapshot Bill: The Backup Line Item Your Self-Hosting Math Forgot

9 min readDora NodaDora Noda
Share
On this page

On January 1, 2026, backups on Fly.io stopped being free. Volume snapshots — the automatic daily copies Fly takes of every persistent volume — started billing at $0.08 per GB per month, with the first charges landing on February invoices. Most tenants barely noticed: Fly reported that 98% of customers would see no additional charges at all.

But "free for most" is not the same as "free," and this particular line item deserves a closer look than the announcement got. Snapshot billing is the quietest kind of hosted-platform cost: it is on by default, it scales with your data rather than your traffic, and it grows the invoice of a tenant who never asked for backups. If you are weighing hosted against self-hosted — or auditing a Fly bill that crept upward this year — the backup dimension belongs in the spreadsheet. Here is the line-item math.

The change, in one box

Fly announced the change in October 2025 with admirably clear terms. Five numbers tell the whole story:

  • Price: $0.08/GB per month of stored snapshot data, first 10 GB free each month.
  • Metered on stored size, not provisioned size: if you have written 1 GB to a 10 GB volume, the snapshot stores roughly 1 GB. You pay for data, not empty capacity.
  • Incremental: only changes since the previous snapshot consume additional storage. When the oldest snapshot in the chain expires, some of its data rolls into the next one.
  • Automatic daily snapshots on every volume by default, with 5-day retention out of the box. Retention is configurable from 1 to 60 days, and you can disable automatic snapshots entirely per volume.
  • Snapshots cannot be manually deleted. They expire on their retention schedule, and that is the only way they go away.

Two adjacent facts complete the storage picture. Volumes themselves cost $0.15/GB per month of provisioned capacity — billed even when the volume is detached or attached to a stopped Machine. And a stopped Machine's root filesystem is billed at the same $0.15/GB rate: stopped is cheaper, not free.

The line-item math for a typical web-plus-Postgres stack

Take the most ordinary production setup imaginable: a web app with a 10 GB volume holding about 3 GB of uploads and state, plus a Postgres database on a 40 GB volume holding about 25 GB of data. Default settings everywhere — daily snapshots, 5-day retention.

On Fly.io, the storage dimension breaks down like this:

Line itemMathMonthly cost
Volumes (provisioned)50 GB × $0.15$7.50
Snapshots (stored, minus free tier)~28 GB stored − 10 GB free = 18 GB × $0.08~$1.44
Storage total~$8.94

The snapshot line is about 16% of the storage bill here — real money, but not the headline. That ratio is exactly why the charge slipped past most teams: one extra dollar forty-four on an invoice dominated by compute.

On owned Hetzner disks, the same retention looks like this. Hetzner Cloud volumes run about €0.044/GB per month in EU regions, and volume snapshots about €0.011/GB:

Line itemMathMonthly cost
Volumes (provisioned)50 GB × €0.044€2.20
Snapshots (equivalent stored)~28 GB × €0.011~€0.31
Storage total€2.51 ($2.70)

The delta is roughly 3.3× on the storage dimension: ~$8.94 hosted versus ~$2.70 self-hosted for identical capacity and retention. In absolute terms that is about six dollars a month — nobody migrates a database over six dollars. But watch what happens as the data grows, because the two sides of this comparison scale very differently.

What moves the number: size, churn, retention

Three variables control the snapshot line, and the defaults put two of them on autopilot. Stored data grows with your database; retention multiplies how many incrementals you keep; churn — how much of the data changes each day — determines how fat each incremental is. Fly's free 10 GB absorbs the small end entirely, which is why 98% of customers saw nothing. Past that threshold, the bill is linear in all three.

The table below models monthly snapshot cost (after the free tier) at a typical ~2% daily churn for a small Postgres, across stored-data sizes and retention settings:

Stored data5-day retention (default)30-day retention60-day retention
10 GB~$0.06~$0.46~$0.94
30 GB~$1.79~$2.99~$4.43
100 GB~$7.84~$11.84~$16.64

Three things stand out:

  • The free tier plus defaults genuinely cover the small-stack case. A 10 GB database at default retention costs six cents a month.
  • Retention is a quiet multiplier. Bumping a 100 GB database from 5 to 60 days more than doubles the snapshot line, and nothing in the dashboard forces you to confront that tradeoff when you raise it for compliance reasons.
  • Churn is the hidden variable. A write-heavy workload — event ingestion, append-only logs, a busy queue table — fattens every incremental in the chain, so two databases with identical sizes can carry very different snapshot bills.

The honest framing: snapshot billing punishes exactly the workload shape that also punishes every other usage-billed dimension — big, busy, and long-retained. If your database is small and calm, this line item rounds to zero. If it is large and churning with month-long retention, the backup dimension alone can exceed what the entire storage footprint would cost on owned disks.

The defaults audit: three settings to check today

Whether or not you ever leave Fly, the billing change turned three previously inconsequential settings into cost controls. They are worth ten minutes:

  1. Retention per volume. The default is 5 days and the range is 1–60. Every volume that does not need multi-week recovery history — caches, scratch space, ephemeral build state that somehow ended up on a volume — should sit at the low end. Since snapshots are incremental, cutting retention helps most on frequently updated volumes.
  2. The disable switch. Fly added a per-volume option to turn off automatic snapshots entirely. That is the right call for data you can regenerate or already back up another way — but remember the warning in the docs: a Fly volume exists on exactly one server, so disabling snapshots on a volume with no other backup strategy means a host failure takes the data with it.
  3. Orphaned capacity. Volumes bill at $0.15/GB whether attached or not, and stopped Machines keep billing rootfs at the same rate. A volume left behind by a deleted app, or a stopped Machine nobody restarted, keeps charging full storage price indefinitely. fly volumes list across your apps is the cheapest cost review you will run this quarter.

One more operational note: because snapshots cannot be manually deleted, there is no "purge now" button when you discover a bloated chain. Lowering retention only stops the growth; the existing snapshots bill until they expire naturally. Fly gave everyone that grace implicitly — existing snapshots had months to expire before billing began — but going forward, the only fast control is the retention knob turned before the chain grows.

The honest counterweight: when the hosted backup dimension wins

A cost comparison that only totals the invoice is lying by omission, so here is the other side. For the small stack in our worked example, Fly's snapshot line is $1.44 against $0.31 of Hetzner snapshot storage — a $1.13 monthly premium that buys automatic daily snapshots with zero operational work: no cron job, no retention script, no 3 a.m. discovery that backups silently stopped six weeks ago. Inside the free tier it is literally $0.00 for a backup story most side projects would otherwise never build. That is a genuinely good deal, and it is why Fly could truthfully say 98% of customers see no charges.

Self-hosting the backup dimension is cheap in storage and expensive in attention. Hetzner's per-GB snapshot rates are roughly one-seventh of Fly's, but Hetzner volume snapshots are manual: you schedule them, you rotate them, you verify restores. The forcing function that makes hosted backups valuable is not the storage — it is the default. Default-on daily snapshots with 5-day retention mean every Fly tenant has a recovery story on day one, including the ones who would never have built one. Any self-hosted platform that wants to match that has to make its backup story equally default-on, not equally cheap-per-gigabyte.

So the decision rule is simple: if your data fits comfortably in the free tier, the hosted backup dimension wins on every axis — cost included. If your data has outgrown it by an order of magnitude, the per-GB gap starts paying for real operational automation. The break-even is not a fixed number; it is the point where your snapshot line exceeds the cost of the backup runbook you would have to write anyway.

Backups are the template, not the exception

Step back from Fly specifically and the pattern is worth naming: usage-billed platforms grow revenue by metering dimensions that used to be bundled, and backup storage is the ideal candidate — valuable, invisible, and scaling with success rather than with conscious consumption. Snapshot billing arrived with a free tier, incremental metering, and advance notice; it is about as fair a version of this move as exists. It still quietly added a compounding line item to every growing tenant's bill.

The defense is not outrage, it is instrumentation. Know your stored-versus-provisioned ratio, know your retention settings per volume, and know the per-GB rate your growth compounds against. Run those three numbers once a quarter and no default-on dimension can surprise you — on Fly, or anywhere else usage billing follows.

Self-hosting the whole stack changes this math from a metered line item into a fixed disk cost. Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own, where your backup retention is a config value, not an invoice line. 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