AWS S3 vs Cloudflare R2

Choose R2 if you serve significant traffic out of your bucket — free egress typically cuts the bill by most of it. Choose S3 if you need the deep feature set, storage classes, or tight integration with the rest of AWS. For a public read path, R2 is usually the correct answer and the migration is straightforward.

Editorial judgement last reviewed

Should I move from S3 to Cloudflare R2?

S3 is the reference implementation of object storage and the most feature-complete product in this category by a distance. Storage classes from Standard down to Glacier Deep Archive, Intelligent-Tiering, replication, lifecycle rules, event notifications into the whole AWS ecosystem, Object Lambda, S3 Select, Access Points, and IAM permissions granular enough to satisfy any auditor. If you need one of those things, nothing else on this page does it.

R2 does not try to match that. It implements the parts of the S3 API that most applications use, and it charges nothing for egress. That single pricing decision is the entire pitch, and for a large class of workloads it is decisive: serving five terabytes a month out of S3 costs hundreds of dollars, and out of R2 costs zero.

If your bucket is a public read path — images, video, downloads, static assets, a package registry — move to R2. The savings are large, immediate, and the migration is a data copy plus an endpoint change.

If your bucket is deep inside an AWS architecture — feeding Athena, triggering Lambdas, tiering to Glacier, replicating across regions under a compliance policy — stay on S3. The egress you're paying is probably intra-AWS anyway, and the integration is worth more than the storage rate.

The common architecture is both: S3 for the internal data lake, R2 for anything users download. That's not a hedge, it's just matching the tool to the traffic pattern.

Which one should you pick?

Choose Cloudflare R2 if…

  • You serve files to end users and egress is a visible line on your bill.
  • You want predictable costs — a traffic spike shouldn't produce an invoice you have to explain.
  • You're already on Cloudflare Workers or Pages, where R2 bindings remove a network hop entirely.
  • You're hosting large downloads: installers, model weights, datasets, media.
  • You want a CDN in front of your objects without configuring one.
  • Your usage of the S3 API is the common subset: put, get, list, presigned URLs, multipart uploads.

Choose AWS S3 if…

  • You need storage classes: Infrequent Access, Glacier, Deep Archive, or Intelligent-Tiering to manage a large archive automatically.
  • Your data feeds AWS services — Athena, Redshift, SageMaker, EMR — where keeping the bucket in-region is the whole point.
  • You need S3 event notifications wired into Lambda, SQS or EventBridge.
  • You need IAM at full granularity, cross-account access, VPC endpoints, or an audit trail your compliance team already accepts.
  • You need cross-region replication under a documented policy.
  • Your traffic is mostly internal to AWS, so egress isn't what's costing you.

Egress: the number that drives every migration

AWS charges roughly nine US cents per gigabyte to send data out to the internet, with volume discounts that only matter at large scale. That's about ninety dollars per terabyte. A modest media site serving ten terabytes a month is paying nine hundred dollars just to deliver bytes it already paid to store.

R2 charges nothing. Not a lower rate — nothing. You pay for storage and for operations, and downloads are free regardless of volume or destination.

Our storage hub computes a standard scenario across every provider — 1 TB stored, 5 TB egress, 10 million requests a month, in USD and AUD — and the gap on that shape is not subtle. Egress is where the entire category's economics live, and it's why R2 exists.

Two honest caveats. First, if you put CloudFront in front of S3, your egress is billed at CloudFront rates rather than S3's, which is cheaper — still not free, but the naive comparison overstates the gap for anyone already using a CDN properly. Second, R2's operations pricing is real: Class A operations (writes, lists) cost meaningfully more than Class B (reads). A workload doing enormous numbers of small writes can find that operations, not storage, is its largest line.

For read-heavy public workloads, neither caveat changes the conclusion.

Feature gaps you should check before migrating

R2 covers the common S3 API surface well, but S3 has fifteen years of features and R2 has not reimplemented all of them. Check this list against your code before committing.

Storage classes are the biggest gap. S3 lets you tier cold data to Glacier at a fraction of Standard pricing, which for a large archive is a bigger saving than R2's free egress. R2's model is simpler with fewer tiers — verify the current options against your retention needs.

Event notifications differ. S3's fan out to Lambda, SQS and EventBridge with a mature configuration model. R2's event story routes into Cloudflare's own ecosystem, which is fine if you're building there and awkward if you aren't.

Also verify: object lock and WORM support if you have a compliance retention requirement; versioning semantics; lifecycle rule expressiveness; conditional request and ETag behaviour on multipart objects; and the granularity of access controls, since R2's token model is simpler than IAM and simpler can mean insufficient.

The practical approach is to run your existing integration test suite against an R2 bucket before migrating anything. Most applications pass unchanged. The ones that don't usually fail on exactly one of the items above, and it's better to find out in CI.

How to migrate without an outage

The mechanics are unglamorous and well trodden. Copy the data with rclone or a similar tool, verify checksums, dual-write for a period, cut reads over, then decommission.

Two details make it painless. First, R2 supports migration modes that copy objects on demand the first time they're requested, so you can flip the read path immediately and let the bucket fill in behind you rather than waiting for a bulk copy of many terabytes. Second — and this is the delightful part — AWS does not charge you egress for data leaving to a Bandwidth Alliance partner in the standard way you'd fear, but you should confirm the current terms, because a bulk copy of a large bucket out of S3 can otherwise cost more than a year of R2.

Practical sequence: stand up the R2 bucket, dual-write new objects to both, start the bulk copy of historical objects, verify a sample by checksum, switch reads to R2 behind a feature flag, watch error rates for a week, stop writing to S3, and leave the S3 bucket in place for a month before deleting anything.

Keep your object keys identical. The migration then reduces to changing an endpoint and a set of credentials, and rolling back is changing them again.

Where each one sits in a wider stack

S3's real product is not storage, it's the ecosystem. Query it in place with Athena. Train on it with SageMaker. Trigger workflows with EventBridge. Tier it automatically with Intelligent-Tiering. Govern it with IAM policies your security team has already reviewed. If your organisation runs on AWS, S3 is not a component you're choosing — it's the floor.

R2's real product is delivery. It sits next to Workers, which means an object can be read, transformed and served from the edge without an origin request. Combined with Cloudflare Images or a transform Worker, it becomes an image pipeline. Combined with Cache Rules, it becomes an asset host with a global CDN and no bandwidth bill.

For Australian teams there's a latency dimension worth noting. Cloudflare's network reaches Sydney, Melbourne, Brisbane and Perth, so R2-backed content is served locally regardless of where the bucket lives. S3 has an ap-southeast-2 region in Sydney, which gives genuine data residency — a stronger guarantee than edge caching if residency is a compliance requirement rather than a performance preference. We cover that distinction properly on the Australian storage page.

The wider field — Backblaze B2, Wasabi, Tigris, Storj, Hetzner, Scaleway and the rest — is on the storage hub, compared on the same fields.

Frequently asked questions

Is R2 really free egress?

Yes. You pay for storage and for operations, and data transfer out costs nothing regardless of volume. Class A operations — writes and lists — are the meter that runs, so write-heavy workloads should model those carefully.

Will my S3 code work with R2?

Usually unchanged. Point the AWS SDK at R2's endpoint with the right credentials and the common operations work. Test multipart uploads, conditional requests, ETag handling on multipart objects, and anything using storage classes or event notifications.

Does R2 have Glacier-style archive storage?

Not with S3's depth of tiering. If a large cold archive is your main cost, S3's Glacier tiers can beat R2 outright even after egress, because the storage rate difference is enormous. Model both.

What does it cost to move data out of S3?

Standard egress charges apply to a bulk copy, which on a multi-terabyte bucket is a real one-off cost. Check current terms for transfers to Bandwidth Alliance partners, and consider R2's on-demand migration so you only move objects that are actually requested.

Can I use both?

Yes, and many teams do: S3 as the internal data lake feeding AWS analytics, R2 as the public read path for anything users download. It's the standard architecture once egress becomes visible on the bill.