Contact Us
Webflow Premium Partner Ehab Fayez
Back to Agent Skills
Data & Analytics

Cloudflare R2 Object Storage

Store objects with Cloudflare R2 for zero egress fees, S3-compatible API, and edge-optimized delivery.

Claude Code Cursor Copilot Windsurf

Overview

Cloudflare R2 is an S3-compatible object storage service that eliminates egress fees, making it significantly cheaper than AWS S3 for applications that serve stored content frequently. R2 is automatically distributed across Cloudflare's global network, providing low-latency access worldwide without requiring CDN configuration.

R2 provides full S3 API compatibility, meaning you can use the AWS SDK, rclone, or any S3-compatible tool to interact with it. For Cloudflare Workers, R2 bindings provide direct access to storage without network overhead, enabling fast storage operations at the edge. Public buckets can be accessed through custom domains with automatic TLS and caching.

The service supports objects up to 5 TB, multipart uploads, conditional operations (ETags), and lifecycle rules for automatic deletion. R2 integrates with Cloudflare Workers for server-side processing (image resizing, format conversion), Cache API for edge caching, and event notifications for triggering workflows on upload. Pricing includes free egress, with storage at $0.015/GB/month and operations priced per million.

Who Is This For?

  • Store user uploads with zero egress fees for serving content
  • Migrate from S3 to R2 using the same SDK and tools
  • Process uploaded images with Cloudflare Workers
  • Serve static assets globally through R2 public buckets

Installation

Setup for Claude Code
npm install @aws-sdk/client-s3

Configuration

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"

// R2 uses S3-compatible API
const r2 = new S3Client({
  region: "auto",
  endpoint: `https://${process.env.CF_ACCOUNT_ID}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: process.env.R2_ACCESS_KEY_ID!,
    secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
  },
})

await r2.send(new PutObjectCommand({
  Bucket: "my-bucket",
  Key: "uploads/photo.jpg",
  Body: fileBuffer,
}))