StacksFree Verdict: 9/10. Cloudflare R2 is the best $0-forever object storage for indie hackers who serve or move data OUT of storage — 10 GB free storage, 1M writes and 10M reads per month, and egress that is never billed. The catch: 10 GB fills fast and the free tier does not cover Infrequent Access. Here is how to get started with Cloudflare R2 for beginners: sign up for a free Cloudflare account, complete the R2 subscription checkout (it costs $0), create a bucket, and generate S3-compatible API tokens.
How This Guide Was Built
This guide is based on Cloudflare’s official R2 pricing page and the R2 documentation, verified on September 7, 2026. We verified the free-tier limits, signup flow, S3-compatible credentials, and Workers setup steps. We did not run R2 hands-on — this review is based on official documentation, pricing pages, and community reports. Last verified: September 2026.
What is Cloudflare R2?
Cloudflare R2 is an object storage service that is fully S3-compatible, meaning you can swap it into existing S3 workflows with minimal changes. Unlike AWS S3, R2 charges $0 for egress (data transfer out) with no cap — Cloudflare R2 pricing states egress is always free. This makes it ideal for serving images, videos, or user uploads directly to browsers, where S3’s bandwidth fees would otherwise accumulate quickly. R2 also integrates natively with Cloudflare Workers, Cache, and Access.
How do I get started with Cloudflare R2?
To get started with Cloudflare R2, you must first complete a free “R2 subscription” checkout in the dashboard — this step is mandatory before you can create buckets or tokens, per the R2 get-started docs. The three steps are: (1) create a Cloudflare account and navigate to Storage & databases > R2 > Overview; (2) complete the free R2 subscription checkout — you are only billed if you exceed free limits; (3) create a bucket and an API token. Without this subscription step, the R2 dashboard will show an error and block bucket creation.
Cloudflare R2 Free Tier Breakdown (2026)
The free tier resets monthly and includes these four limits, per Cloudflare R2 pricing:
- Storage: 10 GB-month of Standard storage. This is the only storage class included; Infrequent Access (IA) is paid-only.
- Class A operations (writes): 1,000,000 per month. This covers PutObject, multipart uploads, and CopyObject.
- Class B operations (reads): 10,000,000 per month. This covers GetObject and HeadObject. Deletes are always free.
- Egress: $0, unlimited, forever. Cloudflare does not bill for data leaving R2, regardless of volume.
The paid tier starts when you exceed any limit: Standard storage is $0.015/GB-month, IA is $0.01/GB-month plus $0.01/GB retrieval with a 30-day minimum, Class A ops are $4.50 per million, and Class B ops are $0.36 per million Cloudflare R2 pricing.
Setting Up S3-Compatible Access
R2 exposes an S3-compatible endpoint, so you can use the AWS CLI, rclone, or any S3 SDK. First, create an API token: go to R2 > Manage R2 API Tokens > Create API Token, select “Object Read & Write,” and scope it to your bucket. Copy the Access Key ID and Secret Access Key — the secret is only shown once, per the R2 S3 token docs. Then configure your client:
# AWS CLI (region must be "auto")
aws configure
# enter: Access Key ID, Secret, region = auto
# Upload a file
aws s3 cp file.txt s3://my-bucket/ --endpoint-url https://<ACCOUNT_ID>.r2.cloudflarestorage.com
Your endpoint is always https://<ACCOUNT_ID>.r2.cloudflarestorage.com, and the region is always "auto" R2 S3 API docs. Alternatively, rclone (version 1.59 or newer) supports Cloudflare as a provider, or you can use npx wrangler r2 object put my-bucket/file.txt --file ./file.txt R2 CLI docs.
Building Your First Project with Workers
R2 pairs natively with Cloudflare Workers free tier — Workers free plan allows 100,000 requests per day, and R2 egress from Workers is $0 Workers pricing. To bind a bucket, add this to your wrangler.toml or wrangler.jsonc:
name = "my-r2-app"
main = "src/index.js"
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-bucket"
Then in your Worker script, the binding becomes an env variable:
export default {
async fetch(request, env) {
const url = new URL(request.url);
const key = url.pathname.slice(1);
// Read
const object = await env.MY_BUCKET.get(key);
if (object === null) return new Response("Not found", { status: 404 });
return new Response(object.body);
// Write (PUT request)
// await env.MY_BUCKET.put(key, request.body);
}
}
Test locally with wrangler dev (it simulates R2 locally) and deploy with wrangler deploy, per the R2 Workers API docs.
Public Access and Custom Domains
R2 offers an automatic .r2.dev subdomain for every bucket, but it is for development only — Cloudflare rate-limits it and explicitly warns it is not production-safe, per the public bucket docs. For production, attach a custom domain to the bucket from the R2 dashboard. This gives you access to Cloudflare Cache, WAF, and Access controls. Note that R2 does not provide directory listing at the domain root — you must request a specific object path. For private files, use presigned URLs that expire after a set time.
Cloudflare R2 vs Backblaze B2
Both R2 and Backblaze B2 offer 10 GB free storage, but they serve different use cases, per Backblaze pricing and Cloudflare R2 pricing. B2 charges $6.95/TB-month and offers free egress up to 3x your average monthly storage, then $0.01/GB (with unlimited free egress via partner CDNs). R2 charges $0.015/GB-month and has unlimited $0 egress. R2 wins for read-heavy apps served directly to users or via Workers; B2 wins for cold archives and bulk backups where you rarely read data. See our Backblaze B2 free tier guide for full details.
Common Mistakes to Avoid
New R2 users hit the same walls. First, skipping the R2 subscription checkout — you cannot create a bucket until you complete the $0 signup. Second, using the .r2.dev domain in production; it is rate-limited and not reliable. Third, forgetting that the free tier excludes Infrequent Access — if you select IA as your storage class, you are billed immediately. Fourth, hardcoding the AWS region instead of "auto", which causes auth failures. Fifth, assuming the secret access key is recoverable — if you lose it, you must create a new token.
FAQ
Is Cloudflare R2 really free?
Yes, for the defined free tier: 10 GB-month Standard storage, 1 million Class A writes, 10 million Class B reads, and unlimited $0 egress, as stated on Cloudflare R2 pricing. You complete a $0 subscription checkout in the dashboard, and you are only charged if you exceed these limits.
How does Cloudflare R2 compare to AWS S3?
R2 is S3-compatible, so most S3 SDKs work without modification. The core difference is pricing: AWS S3 charges per-GB egress fees, while R2 charges $0 for egress Cloudflare R2 pricing. R2 also lacks some S3 features like lifecycle policies that transition between storage classes automatically.
Can I use Cloudflare R2 with any S3 tool?
Yes, if the tool supports custom endpoints. The AWS CLI, rclone, boto3, and most S3 libraries work by pointing them at https://<ACCOUNT_ID>.r2.cloudflarestorage.com with region "auto" R2 S3 API docs. Tools that require specific AWS regions or features (like S3 Select) may not work.
Where to go next
Start by creating a bucket and uploading a test file via the AWS CLI, then build a simple Worker that reads objects from your bucket and serves them over HTTP. If you need cheaper cold storage, compare with the Backblaze B2 free tier. For the rest of the Cloudflare stack, our Cloudflare Workers free tier guide shows how to run the code that reads from R2, and the Cloudflare R2 directory page keeps a running snapshot of limits and alternatives.
