~/VibeHandbook
$39

Cloudflare

developers.cloudflare.com

R2

What it is

Think of a vast online warehouse where you drop off boxes of files and pick them up later. R2 is Cloudflare's object storage — that warehouse — a place to put files: images, videos, backups, user uploads, build artifacts. It speaks the same (Application Programming Interface — the set of commands tools use to talk to it) as Amazon S3, so most S3 tools and SDKs (Software Development Kits — ready-made code libraries) work against it unchanged. The headline difference is pricing: R2 charges for storage and operations but has no egress fees (no charge for data leaving the warehouse), so serving data out is free.

Strengths

  • Zero egress fees — a major saving for media-heavy or download-heavy apps.
  • S3-compatible API, so existing tooling and libraries just work.
  • Bind it directly to a Worker for reads and writes with no credentials in code.
  • Can sit behind Cloudflare's CDN (Content Delivery Network — a worldwide set of servers that keep copies of files near each visitor) for fast, cached delivery.
  • Scales to large objects and large buckets without provisioning.

Trade-offs

  • Object storage, not a filesystem or — no querying inside files.
  • Operations (PUT/GET/LIST) are billed, so chatty access patterns add up.
  • Strong consistency and features differ in details from S3; check cases.
  • For tiny, frequently-changed values, KV (a key-value store, like a giant dictionary) or D1 (a database) is a better fit.

When to use it

Use R2 for user uploads, generated files, large static assets, data exports, and backups — especially anywhere bandwidth costs on S3 would hurt.

Vibe coding fit

R2 plays well with AI-directed builds because the binding removes the usual credential dance — the writes to env.BUCKET directly. Tell the agent whether files are public (serve via a Worker or custom ) or private (signed access), so it wires delivery correctly. The example binds a bucket and uploads a file from the .

# wrangler.toml
[[r2_buckets]]
binding = "BUCKET"
bucket_name = "uploads"
npx wrangler r2 bucket create uploads
npx wrangler r2 object put uploads/logo.png --file ./logo.png