
September 08, 2026
13 min read
By Kokil Thapa | Last reviewed: September 2026
You need a clear Cloudflare R2 vs AWS S3 cost breakdown before you wire object storage into production. Both expose an S3-compatible API, so your Laravel app can swap drivers with minimal code changes. The bill diverges fast once traffic grows. Egress is the usual shock on AWS. On a real client project I moved public media off S3 after the transfer line item passed storage cost. This guide walks through every pricing line, runs three workload models, and shows where each platform wins for teams shipping on Laravel file uploads with S3, R2, and local storage.
What Does the Cloudflare R2 vs AWS S3 Cost Breakdown Look Like for Storage and API Calls?
Both platforms bill storage by gigabyte-month and charge per request. The headline storage rate is not the whole story. Region, storage class, lifecycle rules, and request volume all shift the total.
As of September 2026, published rates look like this. Always confirm on the vendor pages before you budget a migration.
| Cost component | Cloudflare R2 | AWS S3 Standard (us-east-1) |
|---|---|---|
| Storage (per GB/month) | $0.015 | ~$0.023 |
| Write / list (Class A) | $4.50 per million | ~$5.00 per million PUT/COPY/LIST |
| Read (Class B) | $0.36 per million | ~$0.40 per million GET |
| Egress to internet | $0 | ~$0.09/GB (first 10 TB tier) |
| Free tier (ongoing) | 10 GB storage, 1M Class A, 10M Class B/month | 5 GB + limited requests (12-month account trial) |
| S3-compatible API | Yes | Yes (native) |
| Built-in CDN | Pair with Cloudflare CDN (separate plan) | Requires CloudFront (extra cost) |
R2 storage runs roughly 35% cheaper per GB than S3 Standard in a common US region. API pricing is in the same ballpark. Neither difference alone justifies a migration. The egress column is where the math changes.
For a 500 GB bucket with moderate API use, storage alone might run about $7.50/month on R2 versus $11.50 on S3. That gap is real but modest. Add 2 TB of monthly downloads and S3 adds roughly $180 in egress. R2 adds zero.
Official references: Cloudflare R2 pricing documentation and the AWS S3 pricing page. Cross-check region-specific rates before you commit.
How R2 classifies operations
R2 splits requests into Class A and Class B. Class A covers writes, lists, and deletes. Class B covers reads. This mirrors how S3 bills PUT versus GET. Laravel apps that generate thumbnails on upload spike Class A. Read-heavy storefronts spike Class B.
How S3 adds layers beyond Standard
S3 Intelligent-Tiering, Glacier, and lifecycle transitions change the unit rate. A backup bucket on Glacier Deep Archive might store data at fractions of a cent per GB. Retrieval fees and minimum storage durations apply. R2 offers Standard storage only. There is no cold tier inside R2 today.
For archival backups you rarely read, S3 Glacier can still win on storage cost alone. For hot public assets, Standard pricing is the fair comparison.
How Much Does Egress Cost When You Compare R2 and S3?
Egress is data leaving the provider's network to the public internet. Every product image, PDF download, and video stream counts. S3 charges for it. R2 does not.
AWS publishes tiered egress rates. The first 10 TB per month from S3 to the internet in us-east-1 runs about $0.09 per GB. Rates drop slightly at higher volumes. Traffic between S3 and CloudFront is free, but CloudFront itself bills for edge delivery. You rarely escape transfer fees entirely on AWS unless all consumers sit inside the same VPC.
Cloudflare R2 includes zero egress to the internet. That is the product's main cost advantage. Pair R2 with a Cloudflare CDN and you serve cached objects from edge nodes. You still pay Cloudflare plan fees, but you avoid the S3-to-internet meter.
Run the numbers in terabytes if you serve video or large catalog images. A WooCommerce florist site with high-resolution galleries can move hundreds of gigabytes monthly. On S3 that transfer line adds up fast. I have seen egress exceed compute on international eCommerce storefronts before anyone audited the bucket policy.
Internal AWS traffic is a separate case. An EC2 app reading private uploads from S3 in the same region pays no egress. R2 does not replace that pattern cleanly unless your compute also sits on Cloudflare Workers or you accept cross-provider latency.
How Do You Calculate Total Monthly Object Storage Costs for a Real Workload?
Spreadsheet math beats guessing. Define four inputs: stored GB, monthly egress GB, Class A requests, and Class B requests. Plug them into the rate table. Add any CDN or monitoring extras.
Workload A: Private Laravel uploads (low egress)
Imagine a legal-tech portal storing client PDFs. Storage sits at 200 GB. Egress is 50 GB/month because most access happens through authenticated app routes, not direct public URLs. API volume is 500K reads and 50K writes monthly.
- R2 estimate: Storage $3.00 + Class A $0.23 + Class B $0.18 + Egress $0 = ~$3.41/month
- S3 estimate (us-east-1): Storage $4.60 + PUT $0.25 + GET $0.20 + Egress $4.50 = ~$9.55/month
S3 still costs more, but the gap is small. Either platform works. Pick based on where your app already runs. A portal on EC2 with private S3 access keeps traffic inside AWS.
Workload B: Public media CDN (high egress)
A travel booking site serves 1 TB stored images and 3 TB monthly egress through a public CDN. Reads hit 20 million per month. Writes stay at 200K.
- R2 estimate: Storage $15 + Class A $0.90 + Class B $7.20 + Egress $0 = ~$23/month
- S3 + CloudFront estimate: Storage $23 + API ~$8 + S3 egress to CloudFront $0 + CloudFront egress ~$255 (varies by region) = ~$286/month
CloudFront pricing depends on edge location and commitment discounts. Even with free S3-to-CloudFront transfer, edge delivery fees remain. R2 plus Cloudflare CDN often lands lower for this shape. Validate against your actual cache hit ratio.
Workload C: Backup archive (cold, rare reads)
Nightly database dumps totalling 2 TB on S3 Glacier Flexible Retrieval with 20 GB restored monthly. Storage runs about $8/month on Glacier. Retrieval and request fees add a few dollars. R2 at Standard rates would charge $30 for the same 2 TB because no archive tier exists.
For automated off-site backups to S3, Glacier wins on storage density. R2 is not the right cold-archive target today.
Convert USD estimates to NPR using current rates when you report to Nepal-based clients. The Nepal forex rates tool gives a quick rupee reference. Rs 286 at ~133 NPR/USD is roughly Rs 38,000/month — real money for a small agency site.
A copy-paste cost formula
monthly_cost = (storage_gb * storage_rate)
+ (class_a_ops / 1_000_000 * class_a_rate)
+ (class_b_ops / 1_000_000 * class_b_rate)
+ (egress_gb * egress_rate)
/* Example: R2 public media */
R2 = (1000 * 0.015) + (0.2 * 4.50) + (20 * 0.36) + (3000 * 0)
= 15 + 0.9 + 7.2 + 0
= $23.10/month
/* Example: S3 same workload, direct internet egress */
S3 = (1000 * 0.023) + (0.2 * 5.00) + (20 * 0.40) + (3000 * 0.09)
= 23 + 1 + 8 + 270
= $302/month Adjust rates for your region. Tokyo and Mumbai S3 storage costs more than us-east-1. See choosing the right AWS region for latency, cost, and compliance before you assume Virginia pricing.
When Should You Choose R2 Over S3 for Production Workloads?
Pick R2 when egress dominates your bill and you already use or plan to use Cloudflare for DNS and CDN. Public product images, open API file downloads, and static asset hosts fit well. The S3-compatible API means Laravel's league/flysystem-aws-s3-v3 adapter works with endpoint override.
/* .env for Laravel 12/13 with R2 */
FILESYSTEM_DISK=r2
AWS_ACCESS_KEY_ID=your_r2_access_key
AWS_SECRET_ACCESS_KEY=your_r2_secret
AWS_DEFAULT_REGION=auto
AWS_BUCKET=my-app-assets
AWS_ENDPOINT=https://<account_id>.r2.cloudflarestorage.com
AWS_USE_PATH_STYLE_ENDPOINT=false Full wiring steps live in AWS S3 for Laravel file storage setup. The config block is nearly identical for R2.
Pick S3 when your stack is already on AWS and traffic stays private inside the VPC. EC2, RDS, Lambda, and S3 in one account simplify IAM, VPC endpoints, and billing consolidation. S3 also wins for compliance workflows that require AWS-native audit tools, Object Lock, or cross-region replication to another AWS region.
Pick a hybrid when roles differ. Store nightly backups on S3 Glacier. Serve public marketing assets from R2. I have used this split on production Laravel apps where backup retention policies needed Glacier lifecycle rules but the public blog CDN needed zero egress.
Consider MinIO self-hosted S3 storage if you want zero vendor egress but can operate your own disk on a VPS. Hetzner or DigitalOcean bandwidth allowances can beat both clouds for predictable flat pricing. You trade managed durability and ops time.
What Hidden Costs Catch Teams Off Guard on S3 and R2?
Headline rates hide secondary lines. Budget for these before you sign off architecture.
- S3 request prefix scaling: AWS recommends randomised key prefixes for high write throughput. Poor prefix design does not change price directly, but LIST operations on large buckets get expensive fast. Paginate and avoid full-bucket scans in cron jobs.
- S3 inventory and analytics: Storage Lens and inventory reports bill per million objects listed. Useful for FinOps cloud cost optimisation, but not free.
- R2 minimum storage duration: Deleted objects billed for a minimum storage period on some plans. Check current terms before you use R2 as a transient cache.
- Cross-cloud egress: Moving 5 TB from S3 to R2 incurs S3 egress fees on the way out. Plan a one-time migration cost. Use batch tools during off-peak windows.
- Cloudflare plan requirement: R2 is available on free Cloudflare accounts with included allowances. Heavy Workers or CDN features may push you to paid tiers. Factor the full Cloudflare bill, not R2 alone.
- Monitoring and logging: S3 server access logging writes to another bucket. Those log objects accrue storage and request fees. Disable verbose logging in production unless compliance requires it.
- Data transfer acceleration: S3 Transfer Acceleration adds about $0.04 to $0.08 per GB on top of normal egress. Skip it unless upload latency from distant clients justifies the premium.
Teams in Nepal often pay international cards in USD. A Rs 15,000/month surprise (~USD 113) hurts a small business site. Track costs weekly during the first month after launch. AWS Budgets and Cloudflare's dashboard both expose usage graphs.
For deeper AWS billing discipline, read budgeting AWS and Azure in NPR for startups in Nepal and multi-cloud cost management and FinOps. If you need hands-on tuning after a migration, testing and optimization services cover performance and cost audits.
Laravel-specific gotchas
Spatie Media Library and similar packages generate many small files. A single product with six conversions can produce six PUTs per upload. Multiply by catalogue size before you estimate Class A ops.
Private signed URLs served through your app do not hit public egress if the stream proxies through PHP on EC2. That shifts cost to compute bandwidth instead. Direct browser-to-S3/R2 signed URLs trigger provider egress meters on S3 but still zero on R2.
Versioning doubles storage if you never expire old versions. Enable lifecycle rules to purge non-current objects after 30 or 90 days.
Migration and ops costs (non-metered but real)
A website migration from local disk to object storage touches config, CDN rules, and cached URLs. Developer time often exceeds the first year of storage savings. That is fine if you optimise for scale. It is wasteful if you store 5 GB of brochure PDFs.
Ongoing support and maintenance should include a quarterly storage audit. Orphaned uploads from deleted records accumulate silently.
Key Takeaways
- Storage and API rates between R2 and S3 Standard are close; egress is the line that separates bills on public workloads.
- R2's $0 egress makes it the default choice for high-traffic images, downloads, and open CDN assets paired with Cloudflare.
- S3 wins for private same-region access, Glacier archives, Object Lock compliance, and all-AWS IAM/VPC integration.
- Run the four-input formula (storage, egress, Class A, Class B) before migrating — one-time cross-cloud transfer can cost hundreds in S3 egress alone.
- Laravel apps switch between R2 and S3 with endpoint and credential changes; application code stays on Flysystem.
- Hybrid architectures — Glacier backups plus R2 public assets — often deliver the lowest total cost for mature production apps.
People Also Ask
Is Cloudflare R2 cheaper than AWS S3?
For workloads with heavy public downloads, R2 is usually cheaper because it eliminates egress fees. For small private buckets with minimal transfer, the difference is a few dollars per month. Cold archival on S3 Glacier can beat R2 on storage cost alone.
Does Cloudflare R2 have free egress?
Yes. R2 charges no egress fees for data served to the public internet. You still pay for storage and API operations. Pairing with Cloudflare CDN may add plan costs but not R2 egress meters.
Can I use R2 with Laravel's S3 driver?
Yes. R2 exposes an S3-compatible API. Set AWS_ENDPOINT to your R2 account URL and use the standard Flysystem S3 adapter. See the Laravel file storage guides on this site for full config.
What is the main cost risk with AWS S3?
Unbounded egress to the internet. A viral asset or misconfigured public bucket can generate a large transfer bill within days. Use CloudFront, bucket policies, and AWS Budgets alerts to cap exposure.
Build Object Storage That Matches Your Traffic and Budget
A honest Cloudflare R2 vs AWS S3 cost breakdown always starts with your egress profile, not vendor marketing. Map stored volume, monthly downloads, and request counts. Pick R2 for public-heavy delivery, S3 for AWS-native private workloads and cold archives, or split duties across both. If you want help wiring Laravel storage, CDN rules, and a migration plan, contact us or explore Linux system administration and hosting Laravel on AWS EC2 with RDS and S3 for the full stack picture.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

