Storage price per gigabyte is the number everyone compares first, and it's almost the least useful one here. R2 runs $0.015/GB-month, S3 runs $0.023/GB-month, and MinIO's storage cost is whatever your VPS's disk already costs you. On a SaaS product storing a few hundred gigabytes of user uploads, that spread is a few dollars a month — background noise next to what actually decides this comparison, which is what happens when someone downloads the file back out.
Egress is the axis. R2 charges nothing for it, at any volume. S3 charges for every byte leaving after a small monthly allowance. And MinIO doesn't have a vendor egress bill at all, because there's no vendor sitting between your bucket and the internet — there's just your VPS, and its bandwidth allowance, which is a very different constraint with a very different failure mode. Readers who reach Cloudflare R2 vs S3 vs MinIO for SaaS file storage through a growth or RevOps role will want XenGrowth's revenue operations work alongside this.
Put a number on it using nothing but published rates: a product serving 500 GB of downloads in a month pays $0 on R2. On S3, that's 400 GB past the 100 GB free allowance, at $0.09/GB — $36 for that one month, scaling linearly with every download after. On MinIO, it's not a line item at all; it's 500 GB drawn from whatever traffic allowance your VPS provider sells you, alongside every other byte your app already sends. Storage's few-dollar spread barely shows up next to that.
What does each one actually cost, line by line?
Dimension | Cloudflare R2 | Amazon S3 (Standard, us-east-1) | Self-hosted MinIO |
|---|---|---|---|
Storage | $0.015/GB-month | $0.023/GB-month (first 50 TB) | Your VPS disk cost |
Egress to internet | $0 at any volume | Free first 100 GB/mo, then $0.09/GB | No separate bill — counts against your server's traffic allowance |
Write operations | $4.50 per million (Class A) | $0.005 per 1,000 (PUT/COPY/POST/LIST) | None — local disk I/O |
Read operations | $0.36 per million (Class B) | $0.0004 per 1,000 (GET) | None — local disk I/O |
Free tier | 10 GB-month, 1M writes, 10M reads/mo | None ongoing (12-month new-account tier only) | Whatever capacity your VPS already has |
Stated durability | 99.999999999% (11 nines) | 99.999999999% (11 nines) | Whatever your own disk redundancy provides |
Durability is a wash — both R2 and S3 publish the same eleven nines, achieved the same way, by replicating and erasure-coding data across multiple physical locations so no single disk failure loses anything. MinIO's durability is whatever you build: a single VPS with a single disk gives you the durability of that disk, full stop, unless you're running multiple nodes with real replication, which is a meaningfully bigger operational commitment than clicking "create bucket."
Does switching between them mean rewriting your upload code?
Mostly no. Both R2 and MinIO implement the S3 API surface — the same request signing, the same bucket and object operations, the same SDK calls — specifically so that code written against the AWS SDK keeps working with an endpoint URL change and different credentials. Presigned URLs, multipart uploads, list operations: all present on both. The actual migration cost between any pair of these three is closer to "update an endpoint and a few config values" than "rewrite the storage layer," which is worth knowing before anyone treats picking one as a permanent lock-in decision. The XenGrowth resource library goes further into the operations side of this.
"S3-compatible" is not the same claim as "S3-identical," though, and the gap between those two is where migrations quietly break. Neither R2 nor MinIO mirrors every corner of the S3 API — some newer or more obscure operations, particular header behaviors, or specific storage-class semantics may not have an equivalent on either. The fix isn't avoiding both; it's testing the specific calls your app actually makes against whichever target you're moving to, rather than assuming "S3-compatible" was ever a promise of one-to-one parity.
What does each free tier actually let you run?
R2's and S3's free tiers are both about volume — a fixed amount of storage and requests before metering kicks in. MinIO's is a different shape entirely: its free community tier is described on its own pricing page as a "full-featured, single-node deployment architecture," which is a constraint on topology, not just quantity. Multi-node deployment, replication across machines, and several administrative features sit behind the commercial tiers instead. For a single VPS running one instance, that's not a limitation you'll feel. For anything that eventually needs to survive one server dying without losing data, it's the difference between "free" meaning "free forever" and "free until you need the thing that actually matters."
Does it matter where your bucket physically lives?
It does, and each option handles this differently. R2 rides on Cloudflare's global network, so reads can be served from a location close to whoever's requesting the file regardless of which region the bucket is nominally in. S3 buckets are pinned to a specific AWS region, and reaching them from far away costs real latency unless you put a CDN in front — which, to be fair, most production S3 setups already do. MinIO lives wherever your VPS lives, full stop; a user on the other side of the planet from your Contabo box is going to feel that distance on every request, because there's no edge network smoothing it over unless you build one yourself.
What changed with MinIO in 2026, and why it matters here
This is the part that makes "just self-host MinIO" a different recommendation today than it was a year ago. MinIO's GitHub repository was archived by its owner on 25 April 2026, carrying a notice reading that the repository is no longer maintained. The community edition is now distributed as source code only — no precompiled binaries — so running it means building from source or maintaining your own Docker image, not pulling a tagged release the way you could before. The project's stated direction going forward is a separate product line, AIStor, with a free standalone tier and a paid enterprise tier alongside it. XenGrowth on governed AI marketing workflows approaches this from the AI agents and marketing automation side.
None of that makes MinIO's open-source code stop working tomorrow — software doesn't do that. But "self-host MinIO" now means running unmaintained source you compile yourself, or adopting whatever AIStor's licensing terms turn out to be, and either one is a materially bigger commitment than the phrase "just run the open-source object store" implies. That's worth weighing before betting a production upload pipeline on it going forward.
Egress being "free" on MinIO was always shorthand for "billed by a different meter." In 2026 the maintenance story got added to that same list of things the word "free" was quietly not covering.
Why MinIO's egress isn't actually free
There's no MinIO invoice line for bytes leaving the bucket, which is exactly why it gets pitched as the free option. But those bytes still have to leave a network interface somewhere, and on a rented VPS that interface is governed by a traffic policy that has nothing to do with your object storage software. Contabo, to pick the provider this cluster runs on, markets "unlimited traffic" while its own support documentation says there is no default bandwidth limit at all — only a fair-use policy, under which it reserves the right to throttle a server at its discretion if usage becomes "exceptionally high or disruptive." Serve enough files off a self-hosted MinIO bucket and you're not paying a storage vendor for egress — you're drawing down the same undefined goodwill your app server, your database backups and everything else on that box depend on, with no published number telling you how close you are.
There's a second, quieter operational cost that a pure pricing comparison misses entirely: running MinIO yourself means you're the one keeping it patched, monitoring disk health, configuring TLS in front of it, and deciding what real durability looks like on a single box. A managed object store folds all of that into the per-GB price. Self-hosting trades a metered bill for a maintenance workload — a real trade, worth making deliberately, not one you fall into because the storage software itself has no license fee attached.
That's a genuinely different failure mode from an S3 bill. An unexpected S3 egress charge shows up as a number on an invoice you can budget around next month. A fair-use throttle shows up as your entire application — not just file downloads — running slowly because a burst of user downloads made your box look disruptive, and there is no threshold published anywhere that would have let you see it coming. If AI search, GEO and discovery is the part you are stuck on, XenGrowth on building one SEO and GEO content system is the better reference.
So when does each one actually win?
If you're... | Reasonable pick | Why |
|---|---|---|
Serving files to end users at any real volume | Cloudflare R2 | Zero egress removes the one variable cost that scales with your success — more downloads never means a bigger storage bill |
Already deep in AWS, using S3-adjacent services (Lambda, CloudFront, Athena) | Amazon S3 | Ecosystem integration and existing IAM/VPC setup usually outweigh the egress line item for AWS-native teams |
Running a genuinely private, low-egress internal store on hardware you already operate | Self-hosted MinIO (eyes open on maintenance status) | No per-byte vendor bill at all if traffic is genuinely internal or small — but budget for the source-build maintenance burden |
Unsure how much traffic you'll actually get | Cloudflare R2 | Egress is the cost you can't forecast in advance; removing it removes the biggest source of a surprise bill |
Estimate your actual egress, not just your storage — a product that stores 50 GB but serves it to users 40 times over in a month has an egress bill dozens of times its storage bill on any egress-metered provider
If you're evaluating MinIO, check whether you need multi-node replication or a single node is genuinely enough — the free community edition's supported architecture is a real constraint, not a formality
If you're already paying for AWS elsewhere (Lambda, CloudFront, RDS), price S3 with that context in mind — the egress gap narrows once you're inside an ecosystem that's absorbing other costs alongside it
The verdict, if you need one number to anchor on: for a SaaS product storing and serving user files at any volume that might grow, R2's zero-egress model removes the one cost line that punishes you for succeeding. S3 earns its place when you're already committed to the AWS ecosystem and the egress cost is a known, budgeted quantity rather than a surprise. MinIO earns its place on hardware you already control and traffic that's genuinely low or internal — just go in knowing the project's 2026 maintenance status changed what "self-hosted and free" actually means to build and keep running.
It's worth being honest about what this verdict isn't. It isn't a claim that R2 is strictly better engineering than S3 — S3 has more than a decade of ecosystem depth, more storage class options for cold data, and integrations nothing else on this list can match yet. It's a claim about one specific, common shape of workload: a SaaS product serving files to its own users, where the bill scales with how well the product is doing, and where an unmetered egress model turns growth from a cost risk into just growth. Swap the workload — an internal analytics pipeline that writes far more than it ever reads back out, say — and the egress axis stops mattering nearly as much, which is exactly why this is a comparison to run against your own traffic shape rather than a ranking to copy wholesale.
Whichever backend you land on, the bigger architectural mistake is usually upstream of this comparison entirely — putting user uploads on the same disk as your application in the first place, which is its own separate problem worth fixing regardless of which object store you end up pointing at. Get that part right and this comparison stops being urgent; get it wrong and no amount of picking the cheapest egress model saves you from the redeploy that quietly deletes a directory nobody backed up.
Further reading from XenGrowth
The XenGrowth resource library — what you'll learn: how the commercial side of this work is run, across search, automation and revenue operations.
XenGrowth on governed AI marketing workflows — what you'll learn: how the teams running AI marketing agents keep them governed and measurable.
XenGrowth on building one SEO and GEO content system — what you'll learn: how search and AI-answer visibility get run as a single content system.
Where this work meets go-to-market
If Cloudflare R2 vs S3 vs MinIO for SaaS file storage is part of a growth programme rather than a standalone build, the XenGrowth practice is the companion reading.
Five questions about how files actually move through your product. It follows the same axis the post argues for — egress, not storage price per gigabyte, is what decides this.











