
Cloudflare R2 vs AWS S3: real-world cost comparison including egress and CDN delivery
Most teams don’t blow their S3 budget on raw storage — they blow it on everything around it: egress, API calls, and separate CDN delivery. Comparing Cloudflare R2 vs AWS S3 only on $/GB stored ignores where the real money goes in production. Let’s walk through what actually changes when you move object storage into Cloudflare’s connectivity cloud and pair it with CDN delivery at the edge.
Quick Answer: R2 is designed to collapse storage, egress, and CDN delivery into a single, predictable model. For workloads with significant Internet egress or CDN traffic, that usually translates into materially lower and more predictable costs than S3 + CloudFront — without forcing an app rewrite.
The Quick Overview
- What It Is: Cloudflare R2 is an S3-compatible object storage service built directly into Cloudflare’s global edge network, with zero egress fees to the Internet or to Cloudflare services.
- Who It Is For: Teams that serve web assets, APIs, files, media, or AI workloads at scale and are frustrated by unpredictable AWS egress and CDN line items.
- Core Problem Solved: Eliminates classic “data transfer tax” and CDN double-charging by moving storage onto the same global network that already delivers and protects your traffic.
How It Works (and Why the Cost Model Is Different)
With AWS, the typical pattern is:
- Store objects in S3
- Front them with CloudFront for caching, TLS, edge delivery
- Pay S3 storage + S3 requests + S3→Internet egress + CloudFront data transfer + CloudFront requests
With Cloudflare R2, the pattern simplifies:
- Store objects in R2
- Serve them directly from Cloudflare’s global edge (same network as the CDN, WAF, and Workers)
- Pay R2 storage + R2 operations — no egress fees to the Internet or to other Cloudflare services
From a workload perspective, the mechanics look like this:
-
Store objects in S3-compatible buckets (R2)
- Use S3 APIs and tools (SDKs,
aws s3CLI, Terraform) against R2’s S3-compatible endpoint. - Data is stored across Cloudflare’s distributed infrastructure and reachable from Cloudflare data centers in hundreds of cities.
- You can keep S3 as a primary and R2 as a replicated/dual-write destination, or migrate fully depending on risk appetite.
- Use S3 APIs and tools (SDKs,
-
Serve content through Cloudflare’s edge
- Attach a Cloudflare zone (your domain) to your account.
- Expose R2 objects publicly via R2 custom domains or route them through Cloudflare CDN, WAF, and Workers.
- When a user requests an object:
- If it’s cached at the edge, it’s returned locally.
- If not, Cloudflare fetches it from R2, caches according to your policy, then serves it.
- All this happens without a separate “storage→CDN” egress charge — it’s one network.
-
Add logic, security, and multi-region behavior at the edge
- Use Workers in front of R2 to:
- Implement signed URLs, custom auth, or rate limits.
- Rewrite paths, perform image transformations, or add headers.
- Use the WAF & DDoS protection to inspect requests before they ever reach R2.
- For hybrid architectures, use Cloudflare Tunnels (Argo Tunnel) and Cloudflare One to connect private origins or internal APIs while keeping inbound ports closed.
- Use Workers in front of R2 to:
The practical effect: you stop paying a separate “per GB out” tax for delivering R2-hosted content to end-users, to Workers, or to other Cloudflare services.
Real-World Cost Comparison: Where the Line Items Differ
Below we’ll use directional, rounded numbers to show structure, not quote official pricing (which you should always verify on each provider’s pricing page).
1. Storage ($/GB-month)
-
AWS S3 Standard
- Optimized for durability and performance.
- You pay per GB-month of storage, with higher rates for Standard vs Infrequent Access or Glacier.
- Multi-AZ durability is included, but cross-region replication adds extra cost (storage + replication data transfer).
-
Cloudflare R2
- Pay per GB-month of storage in R2.
- Designed as low-cost, durable storage with a single pricing tier instead of multiple storage-classes to micro-manage.
- No extra fees for egress to the Internet or to other Cloudflare services, regardless of region.
Cost signal: Storage rates are often comparable in the same ballpark. The big divergence appears in data transfer and request paths, not raw GB stored.
2. Egress: Internet, CDN, and Inter-service Data Transfer
This is where the biggest gap emerges.
On AWS (S3 + CloudFront)
Typical charges:
- S3 → Internet egress
- Per GB, varying by region and volume.
- Often the largest single cost for download-heavy workloads.
- CloudFront data transfer
- Per GB for data from CloudFront to the Internet.
- Additional CloudFront request charges (per 10,000 or 1M requests).
- S3 → CloudFront
- Usually discounted vs Internet egress, but not free.
- Inter-region data transfer
- If you replicate or serve objects cross-region, additional per-GB costs.
Net effect: For popular assets, you’re paying both S3 egress / origin fetch and CloudFront delivery plus requests. If you mis-tune caching or serve lots of cache misses (dynamic URLs, short TTLs), that double-charge hurts.
On Cloudflare (R2 + Cloudflare Network)
With R2 integrated into Cloudflare’s connectivity cloud:
- R2 → Internet egress
- $0 egress fee from R2 to the public Internet.
- R2 → Cloudflare services (Workers, CDN, WAF, Cache, AI tooling)
- $0 egress between R2 and other Cloudflare services on the same network.
- Requests/Operations
- You still pay per operation class (reads, writes, puts, lists) at R2’s pricing, but not per GB out.
Net effect: You remove the per-GB tax from the equation entirely for public delivery and for inter-service traffic within Cloudflare.
3. CDN Delivery: CloudFront vs Cloudflare CDN
AWS pattern
- CloudFront in front of S3:
- Data transfer out to Internet is charged per GB by region.
- Request charges per 10,000/1M HTTP/HTTPS requests.
- Additional charges for functions (Lambda@Edge, CloudFront Functions) on top.
If you accidentally send traffic directly from S3 (bypassing CloudFront), you pay higher S3 egress rates, often discovered only when the bill lands.
Cloudflare pattern
- Cloudflare CDN in front of R2:
- CDN delivery is part of the same global network as R2.
- No separate “R2→CDN” egress line item.
- You pay:
- R2 storage
- R2 operations
- Cloudflare plan fees / any applicable request or security add-ons (e.g., WAF, Workers, bot management), but not per-GB egress from R2 itself.
You can also put Cloudflare in front of S3 directly if you’re not ready to move data. That doesn’t remove S3 egress fees, but it can reduce CloudFront costs, consolidate security (WAF, DDoS, bot protection) and make a later migration to R2 simpler.
4. Requests, API Calls, and Operations
Both platforms charge for operations, but the shape is different.
-
S3
- Detailed request classes (PUT/COPY/POST/LIST vs GET vs lifecycle transitions).
- Costs per 1,000 or 10,000 operations, varying by request type and region.
- Cross-region replication adds extra request charges.
-
R2
- Request classes for read/write/list operations, priced per number of operations.
- You can shape traffic with:
- Cloudflare cache rules to minimize origin reads.
- Workers to batch/list once and serve many responses from memory or KV if needed.
For many real-world public content workloads, request charges are materially smaller than egress charges, so the removal of per-GB egress is usually the bigger lever.
Concrete Scenario: Static Site or App Assets
Assume:
- 5 TB stored
- 50 TB/month egress to the Internet
- 100M GET requests/month
- Mix of static assets: JS, CSS, images, downloads
These aren’t official prices — they’re directional to illustrate behavior.
On AWS S3 + CloudFront
Potential line items:
- S3 storage: 5 TB × S3 Standard rate
- S3 requests: 100M GETs + some PUT/LIST
- S3→CloudFront origin fetch: per GB; depends on your cache hit ratio
- CloudFront data transfer out: ~50 TB × per-GB rate
- CloudFront requests: 100M HTTP/HTTPS requests
If your hit ratio is 95%, you still pay for 5% of 50 TB (2.5 TB) in S3→CloudFront, plus 50 TB of CloudFront→Internet. If hit ratio drops, origin fetch costs climb quickly.
On R2 + Cloudflare CDN
Potential line items:
- R2 storage: 5 TB × R2 rate
- R2 operations: 100M reads (reduced by caching) + writes
- R2 egress: $0 for 50 TB to the Internet
- R2→Workers/WAF/CDN: $0 egress
You still want a good cache policy (to reduce read operations and latency), but you’re not playing defense against a per-GB egress cliff where one misconfigured cache rule creates a surprise bill.
Concrete Scenario: AI/ML or Data-heavy APIs
Assume:
- You use object storage for model artifacts, embeddings, or large JSON/Parquet files.
- Downstream services (APIs, AI agents, Workers, other microservices) read these objects frequently.
On AWS
- S3→EC2 / Lambda / SageMaker:
- In many same-region scenarios, data transfer can be discounted or lower, but cross-AZ and cross-region access adds charges.
- If AI inference runs outside AWS, S3→Internet egress adds up quickly.
On Cloudflare + R2
- AI agents, APIs, or Workers running on Cloudflare’s Developer Platform:
- Read from R2 with no egress fee between R2 and Workers.
- Responses to users go out via Cloudflare’s edge with no R2 egress charge.
- For hybrid setups where compute stays on-prem or in another cloud:
- You can still enjoy zero egress from R2 to the Internet, and front your downstream services with Cloudflare One for secure connectivity.
Result: Instead of paying each time your AI stack reaches back to object storage across multiple layers, storage and delivery sit in the same logical network.
Features & Benefits Breakdown
| Core Feature | What It Does | Primary Benefit |
|---|---|---|
| Zero egress from R2 | Eliminates per-GB egress fees from R2 to Internet and to Cloudflare services | Predictable, lower costs for bandwidth-heavy workloads; no “surprise” egress spikes |
| Integrated CDN + WAF at edge | Serves R2 content via Cloudflare’s global edge with security controls inline | Single platform for storage, delivery, and protection; fewer moving parts and cheaper delivery |
| S3-compatible API | Exposes R2 through S3-compatible endpoints and tooling | Easier migration or dual-writing; reuse existing S3-based code, SDKs, and pipelines |
Ideal Use Cases
- Best for bandwidth-heavy public content: Because R2’s zero egress plus Cloudflare CDN drastically lowers cost for assets with high download volume (static sites, media, documentation, software distribution).
- Best for edge-native and AI workloads: Because you can keep data close to Cloudflare Workers and AI agents without paying inter-service data transfer fees, and still serve globally via the same network.
Limitations & Considerations
- Migration effort: Moving large datasets from S3 to R2 or redesigning existing pipelines takes planning.
- Workaround: Start with new buckets or low-risk content (e.g., static assets) and run S3 + R2 in parallel while you validate performance and cost.
- Service integrations and ecosystem: Some AWS-native services expect S3 specifically (S3 event triggers, Glue integrations, etc.).
- Workaround: For tightly coupled AWS workloads, you can:
- Keep “system of record” data in S3 and replicate or dual-write to R2 for public delivery.
- Gradually move only the high-egress/public-facing workloads to R2 while your internal AWS services keep using S3.
- Workaround: For tightly coupled AWS workloads, you can:
Pricing & Plans: How R2 Fits into Cloudflare
Cloudflare R2 is part of the broader connectivity cloud platform:
- Storage and operations are billed per GB and per operation class.
- You can start at lower tiers and scale into Enterprise for advanced controls, SLAs, and support.
From a plan perspective (high level):
-
Standard / self-serve usage:
Best for teams wanting to experiment with R2, move a subset of static assets, or start optimizing egress without a large up-front commitment. -
Enterprise plan:
Best for organizations consolidating security, performance, and storage across many properties — or replacing S3 + CloudFront for front-door web delivery and AI workloads — and needing SLAs, compliance, and advanced support.
For full detail, you’d combine R2 pricing with any plan-based features you use (WAF tiers, Workers usage, bot management, Magic Transit, etc.) to compare vs your current S3 + CloudFront + other-tooling bundles.
Frequently Asked Questions
Does R2 actually eliminate all egress costs?
Short Answer: R2 charges $0 for egress to the Internet and to other Cloudflare services, but you still pay for storage and operations.
Details:
The “zero egress” promise applies to data leaving R2:
- No per-GB charge for R2 → Internet.
- No per-GB charge for R2 → Cloudflare Workers, Cache, or other Cloudflare services.
You still have:
- Storage charges (per GB-month).
- Operation charges (reads, writes, lists).
- Any relevant Cloudflare plan or request-based charges for services like Workers, WAF, or bot management.
When comparing to S3, you should model:
- S3 storage + S3 requests + S3 egress + CloudFront data transfer + CloudFront requests
vs - R2 storage + R2 operations + Cloudflare plan/features, with R2 egress removed from the equation.
Can I use Cloudflare in front of S3 without moving to R2?
Short Answer: Yes, and many teams do that as a first step.
Details:
You can:
- Put Cloudflare CDN + WAF in front of your existing S3-origin site or API:
- Improve performance via Cloudflare’s global network.
- Get unified security (WAF, DDoS mitigation, bot management).
- Potentially reduce CloudFront usage or consolidate multiple CDNs.
- Keep S3 as origin while:
- Measuring traffic, latency, and cost improvements.
- Gradually introducing R2 as a secondary origin (for specific buckets or content types).
- Planning a staged migration or dual-write pattern (S3 + R2).
This pattern lets you adopt Cloudflare’s connectivity cloud with minimal disruption, then unlock more savings when you’re ready to move high-egress buckets onto R2.
Summary
When you compare Cloudflare R2 vs AWS S3 in isolation, the storage pricing looks similar. When you compare R2 + Cloudflare’s global network against S3 + CloudFront + egress, the picture changes: most of the “mystery” on the AWS bill comes from bandwidth and inter-service data transfer, not from storing the bits.
R2 is built into Cloudflare’s connectivity cloud so that storage, CDN delivery, and security share the same global edge. That means:
- Connect: Content is served within ~50 ms of users globally on Cloudflare’s network.
- Protect: WAF, DDoS mitigation, and access controls can sit directly in front of your objects.
- Build: Developers can use Workers and AI tooling against R2 without paying per-GB data transfer between services.
For workloads with significant egress or CDN traffic, especially public content and AI workloads, that unified model usually yields lower, more predictable costs and a simpler architecture than S3 + CloudFront.