Cloudflare Tutorial (8) CF R2 Feature Introduction and Detailed Tutorial on Building an Image Hosting Service Based on R2
This article was last updated 287 days ago. The information within may have evolved or changed; if anything is outdated or broken, please feel free to leave a message in the comments section.
Article Abstract
Addressing the image hosting needs faced by individual webmasters in the early stages of building a website, this article explores the solution of building an image hosting service based on Cloudflare R2 object storage service. With zero data egress fees, an S3-compatible API, and deep integration with the CF network, R2 solves the problems of high server load and complex management brought by traditional image hosting. Through different schemes such as manual upload (beggar's version), regular version combined with the PicGo toolchain, and smooth migration version using Rclone synchronization, a seamless transition from self-built image hosting to R2 is achieved. Practice shows that R2's free tier is sufficient for individual users. Combined with CDN acceleration and security strategies, an efficient and low-cost image hosting system can be built, while also providing the possibility of multi-node disaster recovery and traffic load balancing expansion.
Qwen3-14B · 2026-06-18

Preface

Among the many features of CF, there is a very practical one that I only learned about in recent months, which is the protagonist of this article: R2 (the object storage service provided by CF). Through R2, it can meet an important need that individual webmasters have to face in the early stages of building a website: image hosting.

Additional Knowledge: What is an image hosting service and why do we need one?

An image hosting service is an online service specifically designed to store and manage images. Users can upload images to the image hosting service, which will generate a link. Through this link, users can display images on web pages, blogs, social media, forums, and other platforms without directly storing the images on these platforms.

In the process of building a website, an image hosting service can not only improve performance but also reduce costs, simplify management, and enhance security, making it crucial for the successful operation of a website.


Broadly speaking, an image hosting service is a presentation effect: a link that can display the stored image content ashttp(s)://*.png(or other image formats) type of link. For example, when building a website with WordPress, if you want to insert an image into an article, you only need to upload the image to the built-in media library, and a URL will be generated:

image.png

The URL format corresponding to the Sun Wukong image in the picture above is similar tohttps://blog.tangwudi.com/wp-content/uploads/xxxx/xx/孙悟空.jpg, which is the most basic and simplest built-in image hosting service for a website.

However, this built-in image hosting service has several disadvantages:
• Increases website server consumption
Under high user traffic, it will cause additional resource and bandwidth consumption on the website server (though this can be mitigated by a CDN).
• Increases website server operation and maintenance pressure
As the number of images increases, it consumes website server disk space and is unfavorable for operation and maintenance (such as bulk image uploads, site migration, redundant site switching, etc.).
• Unfavorable for separating website text and image content strategies
In many cases, the strategies for website text content and images need to be formulated differently (caching strategies, hotlink protection, etc.). This approach makes the configuration logic more complex and harder to compromise when configuring strategies.

For the above reasons, the image hosting service mentioned in this article does not include this built-in type, but only refers to an independent image hosting service that provides services separately from the website.


There are various ways to implement an image hosting service, including self-built servers (VPS, NAS, or open-source image hosting systems like Chevereto), social media or free services, P2P distributed storage systems like IPFS, and object storage.

Among them, due to scalability and ease of use, using object storage as an image hosting service is very popular in many scenarios and is also the focus of this article.

Note: Self-built image hosting also has its own advantages. For example, using Chevereto to build your own image hosting service allows you to manage your own images and add watermarks to them. Interested friends can refer to the article:Docker Series: Using Docker to Build Your Own Image Hosting Service Based on Chevereto、Tips and Tricks Series: Using Chevereto to Add Watermarks to Images。

Additional Knowledge: Object Storage (COS)

What is object storage?

Object Storage(Cloud Object Storage) is a technology that stores data as objects. Each object includes the data itself, associated metadata, and a unique identifier. Object storage is different from typical file systems. File systems manage data in a hierarchical structure of directories and files, whereas the management unit of object storage is the ”bucket”:bucket。

Comparison between object storage and file systems

Object storage is somewhat abstract compared to the file systems we have long been accustomed to in our daily lives. Especially in practical use, some object storage services provide functions similar to file systems, such as supporting multi-level “folder” structures. This may make the two look very similar on the surface. However, they differ greatly in their underlying working principles and application scenarios, which can be compared from several aspects:

Data storage structure:

• File system: Data is stored in directories in the form of files, and directories themselves can contain subdirectories, forming a tree structure. Each file has a path in the file system, such as /home/user/documents/report.pdf.
• Object Storage: Data is stored as objects, with each object including the data itself, metadata (information describing the data), and a unique identifier. Object storage does not use traditional file paths or directory structures. Although some object storage services support organizing data through “buckets” and “folders”, these are conveniences provided at the logical level, and there is no actual file directory structure underneath.

User experience:

• File system: In a file system, users can intuitively create folders, organize files, and access files through paths. File systems are very suitable for small files that require complex directory structures and frequent read/write operations.
• Object Storage: In object storage, users store data as ”Objects” and retrieve data through unique identifiers (such as URLs) when accessing them. Although objects can be organized using “buckets” and “folders”, these are only logical groupings, and there is no actual directory structure underneath.

For example, in the objects of a specific R2 bucket, there is an option to ”view prefix as directory”. If unchecked, it shows its true form, where directories do not exist at all:

image.png

If checked, directories appear:
image.png

Therefore, directories are just an illusion to object storage, nothing but a ”trick”.

Application scenarios:

• File system: Suitable for handling files that require complex hierarchical management and permission control, such as operating systems, office documents, code repositories, etc.
• Object Storage: Widely used in cloud computing scenarios to store large amounts of static data, such as media files, backups, logs, data lakes, web hosting, etc.

Access methods:

• File system: Accessing data through file paths, which appear as intuitive hierarchical structures to users.
• Object Storage: Accessing data through APIs, where data is located via URLs or identifiers. The provided folder structure is only for the convenience of users to organize data, while actual access relies entirely on identifiers.

In summary, although the “folder” structure of object storage “buckets” in the user's perception is similar to a file system, at the underlying level, they work completely differently: file systems rely on directory structures, while object storage is based on object and metadata management.

Although this difference may not be obvious in the user interface, it has profound implications for performance, scalability, and use cases: object storage excels at handling massive amounts of unstructured data, providing powerful data management and distribution capabilities, while file systems and block storage are better suited for structured data processing that requires low latency and high-performance storage.

Note: For those who like to tinker and want to build their own object storage, it is also possible. You can refer to the articleDocker Series: Building a Private COS Platform Based on MinIO, but this kind of deployment is suitable for friends who have a public IP (currently, if deploying in China, a registered domain name is also required). You can use a cloud host with a public IP or home broadband to build it yourself.

What is R2?

R2 is an object storage service provided by CF, aimed at providing a highly cost-effective cloud storage solution. Compared with other traditional cloud storage services (such as Amazon S3), it has the following advantages:

  1. No egress fees: A significant advantage of R2 is that there are no data egress fees, meaning users are not charged when downloading data directly from R2, which stands in stark contrast to other storage services (such as Amazon S3 and Tencent Cloud COS).
  2. S3 compatibility: R2 is fully compatible with the Amazon S3 API, so users can easily migrate existing S3 data to R2 without modifying code.
  3. Network integration with CF: R2 is tightly integrated with CF's global edge network, providing fast data access speeds and low latency, especially when combined with other CF services (such as Workers or CDN).
  4. Low cost: The storage cost of R2 is relatively low, making it highly attractive, especially for large amounts of frequently accessed static content.

However, R2 is not a free service (which is why it was referred to as ”highly cost-effective” earlier); it merely provides a free tier:
• Storage: 10 GB of free storage space.
• Class A operations: 1 million free operations per month. These operations include PUT, POST, COPY, DELETE, etc.
• Class B operations: 10 million free operations per month. These operations include GET, HEAD, OPTIONS, etc.
• Outbound traffic: 10 GB of free outbound traffic.

However, this free tier is completely sufficient for individual webmasters. For example, taking my blog's image hosting data from August 1st to August 14th as an example:

image.png

The images only total 430 MB (which is exactly 1 year's worth of data since I started learning to build my personal blog at the end of last August). At this rate, it will take more than 20 years of hard work to use up the 10 GB of free storage space. Class A operations are at 2,000, and Class B operations are at 100,000, which are still a ”tiny” bit away from the free tier limits of 1 million and 10 million, respectively. As for the 10 GB of outbound traffic, this is to cover a few special occasions; under normal circumstances, traffic routed through the CF network is free (and generally, content has to go through a free CDN first), so the vast majority of normal usage will not generate outbound traffic.

Therefore, for individual webmasters, the statement ”R2 is free object storage” is quite reasonable, isn't it (let's keep getting things for free to the end!)?

Note 1: Activating R2 requires binding a valid international credit card (after all, it is not a ”truly” free service, which is understandable), such as Visa, Mastercard, American Express, Discover, etc. This is considered the only barrier to using R2.

Note 2: For those who do not have an international credit card, or simply do not have any credit card at all, you can try binding R2 through PayPal, as PayPal can directly bind domestic credit cards or debit cards. Thanks to group member NoahRuiz449 for this tip.


Why did CF name its object storage service R2? Out of curiosity, I did some research. Here are two possible reasons, though their authenticity cannot be verified:
A tribute to popular culture

The name might refer to the droid character R2-D2 from Star Wars. R2-D2 is a highly popular character known for its reliability and importance. CF might have used this name to imply that their storage service is equally reliable and plays a crucial role across the entire network. Additionally, the name R2 is concise and easy to remember, which fits CF's product naming style.
Benchmarking against Amazon S3

CF naming its object storage service “R2” might be a way to establish some connection or comparison with Amazon S3 (this suspicion is inspired by F5 and A10):

• Continuation of alphanumeric naming: Amazon S3 is a widely used object storage service, where “S3” in the name stands for “Simple Storage Service”. CF's choice of the name “R2” might be a continuation of a similar naming pattern while maintaining uniqueness and brand recognition.
• Competition and comparison: R2 is not only similar to S3 in name but also compatible with S3 in functionality, and it emphasizes no data egress fees, making R2 a direct competitor to S3. Therefore, naming it “R2” might also be a clever way to suggest it is similar to S3 but offers differentiated advantages.


Building an R2-based image hosting service

R2 image hosting service usage tutorial (Beggar's Version)

Follow the steps below to manually upload images to R2 and generate an HTTPS-type image link without relying on other tools.

Step 1: Create a storage bucket:

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

The URL in the red box in the image above can also be written directly ashttps://demo.tangwudi.com/孙悟空.jpg, because孙悟空.jpgis uploaded directly to the ”root directory” of the bucket (in quotes because the so-called ”directory” is just an illusion).

Then process other required images in turn, and finally convert the URLs of each image into the required format and insert them into the designated positions in the article.


Note: Therefore, if there is a ”directory” in the storage bucket, the format of the above link will change accordingly. For example, if you place SunWukong.jpg in folder ”1” and then directly upload the folder "1", the above link will become:https://demo.tangwudi.com/1/孙悟空.jpg, which is also a key point during image hosting migration, as long as the original image hosting's method of saving images and outputting URLs is also/目录1/目录2/···/xxx.pngThis format can be directly migrated to R2 (of course, it can also be migrated to object storage services of other providers).


This is the most basic way to use R2. While it works, very few people actually use it this way (unless they occasionally upload a few images just to get a URL). This is because you have to take a screenshot, save it locally, upload it from your local machine to R2, generate the image link on R2, and finally convert the link into the required format to insert into your local article... Isn't that a hassle?

R2 image hosting service usage tutorial (Regular Version)

The conventional way to use R2 as an image hosting service is to use a common editor (like Obsidian or Typora) + PicGo (an image upload tool) along with R2 to quickly upload images and get their URLs. Taking taking a screenshot and pasting my blog's homepage into an article as an example:

Step 1: Use screenshot software to capture a screenshot:

image.png

Step 2: Paste it where you need the image in the article, and a prompt box will appear:

image.png

This prompt appears because I enabled the timestamp renaming feature in PicGo. I won't go into detail here; just click "OK" in the red box.

Step 3: Then, the screenshot will appear at the designated position in the article, and the address in the corresponding format (Markdown format here) will be automatically generated, as shown below:

image.png

In other words, you just take a screenshot, paste it where you need the image in the article you are writing in your editor, click confirm, and the image will be uploaded to R2 directly via PicGo's S3 plugin. It will then generate the image address in a specific format (Markdown, HTML, URL, UBB, custom) at the corresponding position in the article based on PicGo's image format settings. Compared to the previous method of using R2, this way is much more efficient (which is why I called the previous one the "beggar's version"), and this method requires using R2's API.


Note: For the specific settings of Obsidian + PicGo, you can refer to my previous article:Tips & Tricks Series: Achieving Efficient Image Uploading and URL Retrieval with Chevereto + PicGo + Obsidian, except that the image hosting service I used in that article was Chevereto, so the PicGo plugin used was for Chevereto. If you switch the image hosting service to R2, just replace the PicGo plugin with the S3 one.


The process of creating an R2 API is as follows:

image.png

image.png

image.png

In my previous article, I used a self-hosted Chevereto image hosting service, so the PicGo plugin was also Chevereto's upload plugin. You need to change it to install the S3 plugin instead:

image.png

Configure the settings parameters of the S3 plugin as shown in the image below:
image.png

Using this method, daily screenshots are uploaded directly to the R2 image hosting service, which is also good. However, if you have other requirements, such as adding watermarks to images, this method won't work.

Note: There is a secondary development software based on PicGo on GitHub called ”PicList”, which is said to support lossy/lossless compression, format conversion, and adding watermarks to images. However, I haven't used it, so you can try it if you are interested.

R2 usage tutorial (Smooth Migration Version)

Because I previously used a self-hosted Chevereto image hosting service and got used to adding watermarks to my images, even though I now use R2 as my main image hosting service, I still want my watermarks on the images. But I don't want to go through too much trouble. Simply put, I don't want to touch any of my previously used configurations for Obsidian, PicGo, and Chevereto, yet I still want to use R2 as my image hosting service (just that stubborn). Is that possible? Of course it is. This is the core of this section, suitable for those who use a self-hosted Chevereto image hosting service and want to smoothly migrate their main image hosting service from Chevereto to R2.

The core of this smooth migration is ”Rclone”. Rclone is a powerful and flexible command-line tool mainly used for managing and syncing files and directories between different storage services. It supports a wide variety of cloud storage services, local storage devices, and other remote file systems, allowing users to easily copy, move, and sync files and directories between these different storage locations.

To complete the smooth migration from the Chevereto image hosting service to the R2 image hosting service, we need to use Rclone to copy all the images in the local directory of the Chevereto image hosting service to R2. In the future, whenever there are updates in the Chevereto image hosting service, we can have Rclone quickly sync the updates to R2 in an incremental manner. In fact, at this point, you will have two image hosting services: one is Chevereto, and the other is R2. Normally, images are uploaded directly to the Chevereto image hosting service and then synced to the R2 image hosting service using Rclone.

If you want to make R2 the main image hosting service, you only need to assign Chevereto's original domain name to R2 as a custom domain. The detailed operation process for this part will not be discussed in detail in this article. Interested friends can refer to the article:Home Data Center Series: Building an Off-site Disaster Recovery Image Hosting for Chevereto Using rclone and Cloudflare R2。

Precautions for using R2

What needs to be emphasized again is:R2 is not a free service; it's just that the free tier it provides is basically equivalent to free for the vast majority of personal webmasters under normal usage scenarios., so to avoid usage risks, please pay attention to the following points:

Free Tier and Over-limit Fees

• CF R2 provides a certain free usage tier (such as storage space and request counts), but once these free limits are exceeded, users will start to incur charges. Therefore, monitoring usage is very important to avoid unexpected overspending (normal use is very safe; what is feared is abnormal use).

Security and Access Control

• To prevent unauthorized access or hotlinking/abuse, ensure your R2 bucket is configured with appropriate access control policies: you can use CF Access, IP restrictions, or custom permission policies to limit who can access your bucket and data.

• Avoid exposing API keys or other sensitive information in public repositories or codebases, as this could lead to unauthorized access.


Actually, there are other options for the public access part of R2, such as the ”R2.dev subdomain” or ”CORS policy”, but the default options have no issues in terms of security and are suitable for most people, so I didn't mention them. Friends with special needs can change them on their own (friends who don't understand should not mess with them; for example, the R2.dev subdomain is disabled by default, and if this option is turned on and abused by others, the consequences could be quite serious~~), as shown in the figure below:

image.png


Preventing Abuse

• If your R2 bucket hosts publicly accessible content, consider setting bandwidth limits or using other CF protection mechanisms (such as Rate Limiting, WAF) to prevent malicious users from abusing your resources with a large number of requests (general personal webmasters don't really need to worry too much about this, after all, there isn't much traffic to begin with~).

• Regularly review your R2 usage logs to quickly identify and respond to suspicious activity.

Monitoring and Alerts

• Keep track of your usage in a timely manner by setting up monitoring and alert systems. For example, you can use CF's analytics tools or third-party tools to monitor storage and request usage, and set alert thresholds to receive reminders when approaching the free tier limits.

Backup and Data Recovery

• Although R2 is a reliable storage service, regularly backing up critical data is still a good practice to prevent data loss or unforeseen service interruptions (so, in fact, the combination of Chevereto and R2 provided by the smooth migration scheme can also be regarded as a disguised backup).

Afterword

Actually, the reason I messed around with the so-called ”smooth migration” scheme was that I didn't know about R2 before, and I didn't dare to use Tencent Cloud's COS (fearing that images would be hotlinked, wasting CDN traffic). Therefore, the problem I considered before was how to implement a multi-node fault tolerance mechanism for self-hosted Chevereto (see article:Home Data Center Series: Chevereto Image Hosting Multi-Node Scheduled Auto-Sync Tutorial); and the reason for considering the multi-node fault tolerance mechanism of Chevereto was to solve the problem of the image hosting service being unavailable when the ”home data center” had issues (power outage or network disconnection at home) and WordPress switched to Tencent Cloud's lightweight server (see article:Home Data Center Series: Flexibly utilizing Cloudflare Tunnel to achieve automatic takeover by disaster recovery site when the main WordPress site fails) (after all, the main image hosting service was also in the ”home data center”).

Later, when I learned about R2, I initially thought it could be used as a disaster recovery image hosting service when the ”home data center” failed. However, after enjoying using it, it became my main image hosting service... If I had known about R2 from the very beginning (crucially, knowing that I could get it for free), I wouldn't have messed around so much and taken such a long detour: directly using R2 as the main image hosting service. Whether I want to use multiple WordPress sites for fault redundancy (see article:Home Data Center Series: Flexibly utilizing Cloudflare Tunnel to achieve automatic takeover by disaster recovery site when the main WordPress site fails), or use multiple WordPress sites for traffic load balancing (see article:Home Data Center Series: Utilizing Cloudflare Tunnel to Build Active-Active Redundant Sites with Traffic Load Balancing for Dynamic Blogs), I can use a consistent image hosting address, and I wouldn't have to worry at all about whether the image hosting service is available during a failure.

Note 1: Backblaze B2”s object storage service is actually similar to CF R2, also offering 10G of free storage space. Moreover, since Backblaze and CF both belong to the ”Bandwidth Alliance" (Bandwidth Alliance), so outbound traffic between Backblaze B2 storage and CF's CDN service is free within the alliance, which means that if you use Backblaze B2 storage and distribute content through CF CDN, you also do not need to pay outbound traffic fees. And Backblaze B2 has a major advantage: no credit card required! So if you cannot use CF R2 due to credit card issues, you can use Backblaze B2 as an alternative, and the effect is the same.

Note 2: Generally, the R2 image hosting is paired with CF's regular CDN (Cache Rules or Page Rules). The loading speed is just passable, usually requiring 2-3 spins, which is acceptable. However, there is actually a way to optimize it, which is the Worker optimization method I mentioned in CF Series Tutorial (7). It uses the code optimized for static content at the end of the article to accelerate the loading speed of images in the image hosting. But this method is limited by the 100,000 requests per day for Workers in the Free plan. If there are many visitors, the quota may be exhausted (after all, an article may have ten or twenty images, and during optimization, the consumption rate of Worker requests is ten or twenty times faster than just loading an article). Therefore, sites with high traffic and many images should use this method with caution.

Note 3: In addition to being used as an image hosting, R2 can of course be used for other purposes, such as storing audio, video, or files in any other format (anyway, the free storage space is only 10G, just use it up~), and then using it in conjunction with CDN. However, although it is basically free, everyone should also pay attention to the limit. If the CDN traffic is too large and exceeds the normal scope of personal use, account suspension is not impossible (for example, hundreds of TBs of CDN traffic~).

📚 Series Articles: Cloudflare Tutorial (8 / 10)

View Related Categories · 3 Matches
📌 Content Structure Prompt:
This content is part of the following knowledge map, where you can view the complete content path: Cloudflare Learning Map。
📎 Related Articles
Share this article
The blog content is original, please indicate the source when reposting! The RSS address of the blog is:https://blog.tangwudi.com/feed, welcome to subscribe; if needed, you can join theTelegram Groupto discuss questions together.
No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗ
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
Kaomoji
Emoji
Little Dinosaur
Flower!
Previous
Next
       

👋 Welcome to “Wudi's Personal Blog”

Here, long-term exploration is mainly carried out around the following directions:

🧱 Personal Digital Infrastructure and Blog System Construction
☁️ Cloudflare and Network Architecture Practice
🧠 AI and Knowledge System Exploration
🛡️ Network Security and Access Optimization
🎵 Music and Sound Cognition
👁️ Cognitive Perspectives and Worldviews