Your app needs to store files. User avatars, document uploads, product images, generated PDFs — at some point, you need somewhere to put binary data that is not your database. This is where object storage comes in, and the choice you make here has a direct impact on your monthly bill.
The three most relevant options for vibe coders are Cloudflare R2, AWS S3, and Supabase Storage. We will also cover Uploadthing as a developer-friendly wrapper for simpler use cases. This comparison focuses on what matters: pricing at different scales, egress fees, free tiers, and how easy each option is to integrate into a vibe-coded project.
Object Storage Explained in 60 Seconds
Object storage is a system for storing files (called "objects") in flat containers (called "buckets"). Unlike a filesystem with folders and hierarchies, every object is identified by a unique key (think of it as a file path) and stored with metadata. You upload files via an API, and you retrieve them via a URL.
AWS invented the modern version with S3 (Simple Storage Service) in 2006. Every other object storage service is, to varying degrees, an S3-compatible alternative. This means they often use the same API, so code written for S3 works with R2 or other providers with minimal changes.
The key pricing concepts:
- Storage: How much you pay per GB stored per month.
- Operations: Charges per API request (uploads, downloads, list operations).
- Egress: The cost of data leaving the provider's network. This is the one that surprises people.
The Egress Fee Trap
Egress fees are the most important thing to understand about file storage pricing. Every time a user downloads a file from your storage — viewing an image on your site, downloading a document, streaming a video — you pay for that data transfer.
AWS S3 charges $0.09 per GB of egress. That does not sound like much until you do the math. If your app serves 1,000 product images per day at 500KB each, that is about 15GB of egress per month, costing $1.35. Manageable. But if you are serving larger files — PDFs, videos, high-resolution images — egress can easily become your largest infrastructure cost.
This is exactly why Cloudflare R2 exists. Its headline feature is zero egress fees. You pay for storage and operations, but data leaving R2 is free. For many vibe-coded apps, this single difference makes R2 the obvious choice.
Quick Comparison
| Feature | Cloudflare R2 | AWS S3 | Supabase Storage |
|---|---|---|---|
| Free storage | 10 GB | 5 GB (12 months only) | 1 GB |
| Storage cost/GB | $0.015/month | $0.023/month | $0.021/month (Pro plan) |
| Egress cost/GB | $0 (free) | $0.09 | Included in bandwidth allowance |
| S3-compatible API | Yes | Yes (the original) | No (custom API) |
| CDN included | Yes (Cloudflare network) | No (CloudFront is separate) | Yes (via Supabase CDN) |
| Image transformations | Yes (Cloudflare Images, extra cost) | No (need Lambda or third-party) | Yes (built-in resize, crop) |
| Best for | Cost-conscious apps with high traffic | Enterprise, AWS ecosystem users | Projects already using Supabase |
Pricing verified April 2026. Check official sites for current rates.
Cost Projections at Real Scale
Numbers are more useful than feature lists. Here is what each option costs at three scales, assuming moderate read traffic (each stored GB is downloaded an average of 5 times per month):
| Scale | Cloudflare R2 | AWS S3 | Supabase Storage |
|---|---|---|---|
| 10 GB stored | $0 (free tier) | $4.73 ($0.23 storage + $4.50 egress) | $0 (free tier, tight) |
| 100 GB stored | $1.35 | $47.30 ($2.30 storage + $45 egress) | $25/mo (Pro plan required) |
| 1 TB stored | $15.00 | $473 ($23 storage + $450 egress) | $25+ (Pro plan + overage) |
The pattern is stark. At 1TB with moderate traffic, R2 costs $15/month while S3 costs $473/month. The entire difference is egress fees. If your app serves files frequently — images on every page load, downloadable documents, user-generated content — R2 saves you hundreds of dollars monthly.
S3 pricing makes more sense if you primarily store files without serving them to users (backups, data archives, internal processing), or if you are already deep in the AWS ecosystem with CloudFront CDN caching reducing your egress volume.
Cloudflare R2: The Cost Leader
R2 is Cloudflare's object storage service, launched specifically to challenge S3's egress fee model. It uses the S3-compatible API, which means most S3 libraries and tools work with R2 after changing the endpoint URL.
The free tier is generous: 10 GB storage, 10 million Class A operations (writes), 10 million Class B operations (reads) per month. For a typical vibe-coded app with moderate file storage needs, you might never leave the free tier.
Integration is straightforward. If you are using Cloudflare Pages for hosting, R2 fits naturally into your stack. For Next.js apps on Vercel or Netlify, you connect to R2 via the S3-compatible API using the AWS SDK or a library like @aws-sdk/client-s3.
Limitations: R2 does not have the decades of ecosystem that S3 has. Some advanced features — like lifecycle policies, versioning, and event notifications — are available but less mature. If you need complex data pipeline integrations (S3 events triggering Lambda functions, for example), AWS is still the more complete platform.
AWS S3: The Industry Standard
S3 is the original object storage service and remains the default for enterprise applications. The API is the industry standard, the reliability is unmatched (99.999999999% durability, often called "eleven nines"), and the ecosystem of tools that integrate with S3 is enormous.
For vibe coders, S3 is generally overkill. The pricing model is complex (multiple storage tiers, request classes, transfer acceleration options), and the egress fees make it expensive for user-facing file serving. The AWS console is notoriously confusing for newcomers, and IAM permissions are a whole skill set on their own.
That said, if you are already using AWS services — or your AI coding assistant set up your infrastructure on AWS — S3 is the natural storage choice. Pairing it with CloudFront CDN reduces egress costs significantly by caching files at edge locations, though you are then managing two services instead of one.
Supabase Storage: Simple If You Are Already There
Supabase includes file storage as part of its platform. If your app already uses Supabase for its database and authentication, adding Storage means zero new services to configure. Files are managed through the same Supabase client library you already use, and access control integrates with Supabase's Row Level Security (RLS) policies.
The free tier includes 1 GB of storage and 2 GB of bandwidth. The Pro plan ($25/month) gives you 100 GB of storage and 250 GB of bandwidth. Beyond that, overage charges apply.
Strengths: Dead simple if you are in the Supabase ecosystem. Built-in image transformations (resize, crop, format conversion). Auth-aware access control without extra code. The JavaScript client makes uploads trivial.
Limitations: Not S3-compatible, so you cannot easily migrate to another provider later. The free tier's 1 GB is restrictive if your app handles meaningful file uploads. And if you are not using Supabase for other things, adopting it just for storage does not make sense.
Uploadthing: The Developer-Friendly Wrapper
If you just need file uploads in your Next.js app and do not want to think about object storage infrastructure, Uploadthing is worth a look. It is a developer-focused file upload service that handles the upload UI, validation, storage, and CDN serving in a single package.
You define your upload endpoints with a type-safe API, drop in a pre-built upload component, and Uploadthing handles the rest. Storage is backed by object storage behind the scenes (you do not manage it directly), and files are served via a CDN.
The free tier includes 2 GB of storage and 2 GB of bandwidth. Paid plans start at $10/month. It is more expensive per GB than R2 or S3, but the integration time is minutes instead of hours. For MVPs and side projects where your time is more valuable than optimizing storage costs, this trade-off makes sense.
Which One Should You Pick?
The decision is simpler than it seems:
- You want the cheapest option at any scale: Cloudflare R2. Zero egress fees are hard to beat, and the free tier covers most side projects entirely.
- You are already using Supabase: Supabase Storage. Zero additional setup, integrated access control, good enough for most apps. Switch to R2 if you outgrow it.
- You just want file uploads to work with minimum effort: Uploadthing. Higher per-GB cost, but dramatically less integration work.
- You are in an AWS environment or need enterprise compliance: S3. The ecosystem, reliability, and compliance certifications justify the cost.
For the typical vibe coder building a Next.js app with user uploads, start with Supabase Storage if you are using Supabase, or Cloudflare R2 if you are not. Both have free tiers that cover early-stage projects, and R2's pricing means your bill stays low even as you grow. For a full breakdown of costs across your entire stack, see the cost of vibe coding guide.