Introduction to R2 Storage: Buckets and Object Storage
Learn the essentials of R2, Cloudflare's object storage. Master creating buckets, understand object vs. block storage, and navigate R2's egress-free pricing.

Previously in this course, we mastered Introduction to Wrangler CLI: Setup and Project Initialization to manage our Worker environments. Now that we have our development tooling ready, we are moving from compute to state: it’s time to introduce R2, Cloudflare's distributed object storage solution.
Object Storage vs. Block Storage: What’s the Difference?
When you store data in the cloud, the architecture matters as much as the capacity. Developers usually choose between two primary paradigms:
- Block Storage: Think of this as a raw hard drive. Data is split into fixed-size "blocks," each with a unique address. It is high-performance and low-latency, typically used by operating systems or databases (like the D1 database we will explore later). It’s not optimized for internet-scale distribution.
- Object Storage: This treats data as individual objects (a file + its metadata) stored in a flat namespace called a "Bucket." It is designed for scale and accessibility over HTTP. You don't "edit" a file in object storage; you replace it.
R2 is a classic Object Storage service. It is designed to hold your images, videos, logs, and backups, making them instantly available globally through Cloudflare’s network.
Why Choose R2? The Pricing Model
Most legacy cloud providers charge for two things: the space you use and the "egress" (the data sent out of the cloud to the internet).
R2 is different. It follows a zero-egress fee model. This is a game-changer for developers who manage large media libraries or assets. You pay only for the storage used and the total number of operations (Read/Write requests). By eliminating egress costs, R2 removes the "vendor lock-in" tax that makes scaling high-bandwidth applications prohibitively expensive elsewhere.
Hands-on: Creating Your First R2 Bucket
Before we link R2 to our Workers, we need a container for our data.
- Log in to your Cloudflare Dashboard.
- In the sidebar, navigate to R2.
- Click Create bucket.
- Give your bucket a globally unique name (e.g.,
my-app-assets). - Select your preferred location hint (usually "Automatic" is best for global distribution).
- Click Create bucket.
That’s it. You now have an object store ready to receive data.
Worked Example: The Concept of a Bucket
In your local project, imagine you are building an app that stores user-uploaded profile pictures. You don't need a complex folder structure; you simply need a path. In R2, the "path" is just part of the object key.
If you upload a file named avatar.png to the my-app-assets bucket, your object key is simply avatar.png. If you want to simulate folders, you use forward slashes in the key: users/123/avatar.png.
Common Pitfalls
- Case Sensitivity: Bucket names are case-sensitive and must be globally unique across all R2 users. If you get a "Bucket already exists" error, try adding a project suffix.
- Permissions: By default, your R2 bucket is private. You cannot access files via a direct URL until you explicitly configure a Public Access domain or use a Worker to proxy the request.
- Replacing vs. Editing: Remember that object storage is immutable. If you need to change an image, you must upload the new version to the same key to overwrite the old one.
Frequently Asked Questions
Q: Can I mount R2 as a local file system? A: No. R2 is accessed via the S3-compatible API or the Cloudflare Workers R2 API. It is not a POSIX-compliant file system.
Q: Is R2 limited to images? A: Not at all. You can store any binary data, including large JSON blobs, CSV exports, or static site backups.
Q: Does R2 cache my files automatically? A: R2 itself is the storage origin. To get the performance of the CDN, you will eventually pair this with a Worker that serves the file, which we will cover in upcoming lessons.
Practice Exercise
- Create an R2 bucket in your dashboard.
- Use the "Upload" button in the dashboard to manually upload a small text file (e.g.,
test.txt). - Observe the URL provided for the object. Note that it is not publicly accessible until you configure public access.
Recap
We've defined the difference between Object Storage (R2) and block storage, understood why R2’s zero-egress pricing is ideal for web assets, and successfully provisioned our first Bucket. We now have a secure, scalable place to store data for our project.
Up next: Uploading Files to R2, where we will use the CLI to move files programmatically.
Work with me

Custom Email & File Storage System on Cloudflare (Google Workspace Alternative)
Your own private email + file storage suite on your domain — unlimited mailboxes, no per-seat fees. A self-owned Google Workspace alternative for a flat ~$5/month.

Next.js Website & Landing Page Development
A blazing-fast, SEO-optimized website or landing page in Next.js — the kind that loads instantly and ranks. Design-to-code, done right.
