Cloudflare R2は、Cloudflareが提供するS3互換のオブジェクトストレージです。最大の特徴は、インターネットへのデータ転送(エグレス)に料金がかからないことです。この記事では、2026年9月時点の公式ドキュメントとAWSの公開料金データをもとに、料金と無料枠、Amazon S3との違い、使えないS3機能、バケット作成から配信までの手順を整理します。
まとめ:Cloudflare R2の要点
- 料金:Standardは保存$0.015/GB-月、書き込み系(Class A)$4.50/100万回、読み取り系(Class B)$0.36/100万回。エグレスは全ストレージクラスで無料
- 無料枠:毎月10GB-月の保存、Class A 100万回、Class B 1,000万回。Infrequent Accessには適用されない
- S3との差:リクエスト単価はS3東京とほぼ同じで、安くなるのは保存単価とエグレス。転送量が多いほど差が開く
- 互換性:リージョンは
auto。ACL、バケットポリシー、バージョニング、タグ、SSE-KMSはS3 APIとして未実装 - 公開:
r2.devは開発用でレート制限あり。本番はカスタムドメインを接続してキャッシュやWAFを使う
以下、料金の計算方法から順に、導入判断に必要な事実を確認していきます。
Cloudflare R2の位置づけとデータの保存場所
R2は2021年9月28日に発表され、2022年9月21日に一般提供(GA)となりました。S3のAPIを実装しているため、AWS CLIやboto3などの既存ツールはエンドポイントを差し替えるだけで接続できます。耐久性は年間99.999999999%(イレブンナイン)を提供する設計で、全ストレージクラス共通です。これはオブジェクトが失われにくいという指標で、自分で誤って削除したデータを戻せるという意味ではありません。オブジェクトストレージという方式そのものの仕組みはオブジェクトストレージの仕組みとS3互換APIの範囲で解説しています。
保存リージョンの自動選択とロケーションヒント
「R2はデータを世界中に分散して保存する」と説明されることがありますが、現行の仕様は違います。バケットのデータ位置は既定で Automatic で、作成リクエストを出した場所に最も近い利用可能なリージョンが選ばれます。日本から作成すればアジア太平洋に置かれるのが普通で、世界各地で速く読めるのは、カスタムドメイン経由でCloudflareのキャッシュを通したときです。
読み手が作成者と別の地域にいる場合は、作成時にロケーションヒント(wnam・enam・weur・eeur・apac・oc)を指定します。ヒントはベストエフォートで保証ではありません。また、同じ名前のバケットを削除して作り直しても、最初の作成時の場所が使われます。
保存場所を保証する必要があるときは、ジュリスディクションを指定します。EUはバケット作成時に選べます。FedRAMPはEnterprise契約が前提で、アカウントチームかサポートへの申請で使えるようになります。この場合、S3 APIのエンドポイントは https://<ACCOUNT_ID>.eu.r2.cloudflarestorage.com のように地域名が入った専用のものになり、通常のエンドポイントからはアクセスできません。
Cloudflare R2の料金と無料枠
課金対象は、保存容量、Class A操作、Class B操作の3つです。Infrequent Accessにはこれに加えてデータ取り出し料金がかかります。公式の料金表(2026年8月7日更新)は次のとおりです。
| 項目 | Standard | Infrequent Access |
|---|---|---|
| 保存 | $0.015 / GB-月 | $0.01 / GB-月 |
| Class A操作 | $4.50 / 100万回 | $9.00 / 100万回 |
| Class B操作 | $0.36 / 100万回 | $0.90 / 100万回 |
| データ取り出し | なし | $0.01 / GB |
| 最低保存期間 | なし | 30日 |
| エグレス | 無料 | 無料 |
Class Aは PutObject・ListObjects・CopyObject・UploadPart など状態を変える操作と一覧取得、Class Bは GetObject・HeadObject など読み取り操作です。DeleteObject・DeleteBucket・AbortMultipartUpload は無料です。権限が無く401が返ったリクエストも課金されません。
無料枠の範囲とStandard限定の条件
毎月、保存10GB-月、Class A 100万回、Class B 1,000万回までが無料です。この無料枠はStandardにだけ適用され、Infrequent Accessには適用されません。保存量のGB-月は、日ごとのピーク保存量を30日で平均して算出します。1GBを5日、3GBを25日置いた場合は約2.66GB-月です。
エグレス無料はR2から直接出るデータが対象で、Workers API、S3 API、r2.dev 経由の配信が含まれます。R2の前に別の従量課金サービスをつないだ場合は、そのサービス側の料金が発生します。
切り上げ課金とInfrequent Accessの落とし穴
R2の課金は次の課金単位まで切り上げです。100万1回の操作は200万回分、1.1GB-月は2GB-月分として請求されます。Class Aの単位は100万回なので、無料枠の無いInfrequent Accessへ1回書き込んだだけでも、100万回分の$9.00が請求される計算になります。
Infrequent Accessには30日の最低保存期間もあります。1,000GBをInfrequent Accessに5日だけ置いて削除しても、保存料は約167GB-月分ではなく30日分の1,000GB-月($10)が請求されます。さらに、読み取るたびに読んだ量に応じて$0.01/GBの取り出し料金がかかります。1,000GBを1回ずつ全量読むだけで$10となり、保存単価の差(Standardとの差は$0.005/GB-月)で浮く額の2倍です。
Infrequent Accessが向くのは、30日以上置いたまま月1回も読まないバックアップやログです。ライフサイクルルールでStandardから移すことはできますが、Infrequent AccessからStandardへはライフサイクルで戻せず、CopyObject でストレージクラスを指定し直す必要があります。
S3東京リージョンとの月額比較
AWSのPrice List API(AmazonS3は2026年9月26日公開分、AWSDataTransferは2026年9月16日公開分)で取得した東京リージョン(ap-northeast-1)の単価と比べます。書き込み系は1,000回あたり$0.0047、読み取り系は1万回あたり$0.0037を100万回あたりに換算しています。
| 項目 | R2 Standard | S3 Standard(東京) |
|---|---|---|
| 保存(最初の50TB) | $0.015 / GB-月 | $0.025 / GB-月 |
| 書き込み系 | $4.50 / 100万回 | $4.70 / 100万回 |
| 読み取り系 | $0.36 / 100万回 | $0.37 / 100万回 |
| インターネットへの転送(最初の10TB) | 無料 | $0.114 / GB |
リクエスト単価はほぼ同じで、差がつくのは保存単価とエグレスです。1,000GBを保存し、毎月10,000GBをインターネットへ配信する場合で比べます。保存料はR2が無料枠10GBを除いて$14.85、S3東京が$25です。転送料はR2が$0、S3東京が約$1,140(AWS全体の無料枠を差し引く前)です。どちらも操作料金は別にかかりますが、単価がほぼ同じなので差はほとんど転送料で決まります。逆に、配信がほとんどない社内バックアップなら差は保存単価の分だけです。S3側の請求項目の内訳はS3の料金を東京リージョンの実額で計算する方法で確認できます。
S3互換APIの対応範囲と未対応の機能
S3 APIのリージョンは auto です。リージョンを空にできないツール向けに、空文字と us-east-1 も auto の別名として受け付けます。エンドポイントは https://<ACCOUNT_ID>.r2.cloudflarestorage.com です。
オブジェクトの読み書き(GetObject・PutObject・ListObjectsV2・CopyObject・マルチパートアップロード一式・DeleteObjects)とバケットのCORS・ライフサイクル設定は実装済みです。一方、公式の互換表(2026年7月31日更新)で未実装になっている主な機能は次のとおりです。
- ACL(
PutBucketAcl、x-amz-aclヘッダー) - バケットポリシー(
PutBucketPolicy)とパブリックアクセスブロック - バージョニング(
PutBucketVersioning)とS3 APIからのObject Lock - レプリケーション、インベントリ、アクセスログ、静的Webサイト設定
- オブジェクトタグ(
PutObjectTagging) - SSE-S3・SSE-KMSのヘッダー指定(SSE-Cは対応)
- S3形式のイベント通知(
PutBucketNotificationConfiguration)
既存のS3コードが上のいずれかに依存していると、R2に向けた時点でエラーになります。移行前に grep でACLやタグの指定を洗い出しておくと安全です。ストレージクラスは x-amz-storage-class で STANDARD と STANDARD_IA を指定できます。S3側のストレージクラスや権限設計と比べたい場合はAmazon S3の仕組みとストレージクラスが参考になります。
未対応機能を補うR2独自の機能
いくつかの未実装機能には、S3 APIとは別の形で代わりの機能があります。
| S3で使う機能 | R2での代わり | 設定手段 |
|---|---|---|
| Object Lock | バケットロック | ダッシュボード・Wrangler・REST API |
| イベント通知 | Event notifications(Queuesへ送信) | ダッシュボード・Wrangler |
| バケットポリシー | APIトークンの権限・Cloudflare Access | ダッシュボード |
| S3 Tables等のIceberg | R2 Data Catalog(パブリックベータ) | Iceberg RESTカタログ |
バケットロックはプレフィックスごとに保持期間か無期限を指定します。イベント通知は object-create と object-delete の2種類で、バケットあたり100ルールまでです。R2 Data Catalogは通常のR2料金に加え、カタログ操作が月100万回を超えると$9.00/100万回かかります。自動コンパクションを有効にしたテーブルでは、処理量(月10GB超で$0.005/GB)と処理オブジェクト数(月100万個超で$2.00/100万個)も課金対象です。
Cloudflare R2の上限値:容量・オブジェクトサイズ・書き込み頻度
公式の制限値(2026年6月8日更新)のうち、設計に影響するものを抜き出します。
| 項目 | 上限 |
|---|---|
| バケットあたりの容量・オブジェクト数 | 無制限 |
| アカウントあたりのバケット数 | 1,000,000 |
| オブジェクトサイズ | 4.995 TiB |
| 1リクエストのアップロード | 4.995 GiB |
| マルチパートのパート数 | 10,000 |
| 同じキーへの書き込み | 1回 / 秒 |
| キーの長さ・メタデータ | 1,024バイト・8,192バイト |
| カスタムドメイン | バケットあたり100 |
見落としやすいのは同じキーへの書き込み制限です。1秒に2回以上同じオブジェクト名へ書くとHTTP 429が返るため、カウンターや状態ファイルを1つのキーで頻繁に上書きする設計は向きません。5GiBを超えるファイルはマルチパートアップロードが必須です。また、CloudflareのREST API経由の操作はアカウント全体で5分あたり1,200リクエストに制限されているので、大量の読み書きはS3 APIかWorkers APIで行います。
Cloudflare R2の使い方:バケット作成とAPIトークン
APIトークンを発行する前に、ダッシュボードの「R2 object storage」でR2の利用を開始(購入手続き)しておく必要があります。無料枠内で使う場合も同じです。
バケットの作成:ダッシュボードとWrangler
ダッシュボードでは「R2 object storage」から「Create bucket」を選び、名前、ロケーション、既定のストレージクラスを指定します。コマンドラインならWranglerを使います。Wranglerはアカウントに直接ログインするため、アクセスキーは不要です。
npx wrangler login
npx wrangler r2 bucket create my-bucket
npx wrangler r2 bucket list
APIトークンの権限とアクセスキー
AWS CLIやboto3などS3 API経由で接続する場合は、R2専用のAPIトークンを発行し、Access Key IDとSecret Access Keyを取得します。Secret Access Keyは作成直後の画面でしか表示されません。権限は4種類から選びます。
| 権限 | できること | バケット単位の限定 |
|---|---|---|
| Admin Read & Write | バケット作成・削除、設定変更、読み書き | 不可 |
| Admin Read only | バケット一覧、設定参照、読み取り | 不可 |
| Object Read & Write | オブジェクトの読み書き・一覧 | 可 |
| Object Read only | オブジェクトの読み取り・一覧 | 可 |
アプリケーションに渡すのは、対象バケットに限定したObject系の権限が基本です。トークンには、アカウントに紐づくAccount API token(Super Administratorだけが作成でき、失効させるまで有効)と、個人に紐づくUser API token(そのユーザーがアカウントから外れると無効)の2種類があります。退職や異動で止まっては困るサーバー用はAccount API tokenにします。
AWS CLI・boto3から接続する設定
S3互換ツールでは、エンドポイントをアカウントIDの入ったR2のURLにし、リージョンを auto にします。AWS CLIでは aws configure でキーとリージョン auto を設定し、コマンドごとにエンドポイントを渡します。
aws s3api list-objects-v2 \
--endpoint-url https://<ACCOUNT_ID>.r2.cloudflarestorage.com \
--bucket my-bucket
Pythonのboto3では、クライアント生成時に同じ2つを渡します。
import boto3
s3 = boto3.client(
service_name="s3",
endpoint_url="https://<ACCOUNT_ID>.r2.cloudflarestorage.com",
aws_access_key_id="<ACCESS_KEY_ID>",
aws_secret_access_key="<SECRET_ACCESS_KEY>",
region_name="auto",
)
with open("./dog.png", "rb") as f:
s3.upload_fileobj(f, "my-bucket", "dog.png")
ディレクトリ単位の一括転送や同期にはrclone(1.59以降)が向いています。設定時にプロバイダーとしてCloudflare R2を選び、同じキーとエンドポイントを入力します。JavaScriptの場合は @aws-sdk/client-s3 に同じ設定を渡します。SDK自体の使い方はAWS SDK for JavaScript v3の使い方を参照してください。
Cloudflare WorkersからR2を操作するバインディング
Workersからは、アクセスキーを使わず、Wranglerの設定ファイルでバケットをバインディングとして結び付けます。次の記述は、既存のWorkerプロジェクトの wrangler.jsonc に追加する部分だけで、Worker名やエントリーポイントの設定は別に必要です。
{
"r2_buckets": [
{ "binding": "MY_BUCKET", "bucket_name": "my-bucket" }
]
}
コード(エントリーポイントの src/index.js)では env.MY_BUCKET に対して put・get・delete・list を呼びます。get はオブジェクトが無いと null を返すので、404の分岐が必要です。
export default {
async fetch(request, env) {
const key = new URL(request.url).pathname.slice(1);
if (request.method === "PUT") {
await env.MY_BUCKET.put(key, request.body);
return new Response(`Put ${key}`);
}
if (request.method !== "GET") {
return new Response("Method Not Allowed", { status: 405, headers: { Allow: "GET, PUT" } });
}
const object = await env.MY_BUCKET.get(key);
if (object === null) return new Response("Not Found", { status: 404 });
const headers = new Headers();
object.writeHttpMetadata(headers);
headers.set("etag", object.httpEtag);
return new Response(object.body, { headers });
},
};
ローカル開発では注意点が2つあります。wrangler dev は既定でローカルのストレージに読み書きするため、本物のバケットを使うにはバインディングに "remote": true を付けます。また、R2の公式ドキュメント(aws-sdk-js-v3の例)には、wrangler dev でのローカル開発中はS3互換APIを使えないという注記が残っています。一方、workers-sdkリポジトリでは、wrangler 4.115.0以降でローカルのS3 APIと公開バケットのエミュレーションが実験的に使えると案内されています(Discussion #13325)。署名付きURLなどをローカルで試すなら、実験的機能であることを前提にします。この例のコードは認証をしていないため、そのまま公開するとだれでも書き込めます。本番ではヘッダーのトークン確認などを先に入れてください。Workers自体の料金や制限はCloudflare Workersの対応言語・無料枠・料金にまとめています。
R2の公開配信:r2.devとカスタムドメインの違い
バケットは既定で非公開です。インターネットに公開する方法は、Cloudflareが管理する r2.dev のサブドメインと、自分のドメインを接続するカスタムドメインの2つです。
| 項目 | r2.dev | カスタムドメイン |
|---|---|---|
| 用途 | 開発・テスト | 本番 |
| レート制限 | あり(毎秒数百リクエストで429) | r2.devの制限は対象外 |
| Cloudflareキャッシュ | 使えない | 使える |
| WAF・Access・Bot Management | 使えない | 使える |
| 前提 | なし | 同じアカウントのゾーン |
r2.dev は帯域も絞られることがあり、公式は本番用途を想定していないと明記しています。r2.dev にCNAMEを向ける構成もサポート対象外です。カスタムドメインは、同じアカウントにゾーンとして追加したドメインでなければ接続できません。他社DNSを使っているドメインは、ネームサーバーをCloudflareへ移すフルセットアップで追加するのが基本です。他社DNSを残したまま一部のサブドメインだけを通す部分(CNAME)セットアップは、BusinessかEnterpriseプランでしか使えません。
カスタムドメインで配信すると、Cloudflareのキャッシュが効きます。ただし既定でキャッシュされるのは特定の拡張子だけで、全ファイルをキャッシュするにはCache Everythingのルールが必要です。WAFやAccessで保護したら、r2.dev の公開は無効にしておきます。有効なままだとそちらから保護を迂回して読めてしまいます。キャッシュの仕組みそのものはCDNの仕組みとキャッシュ制御で解説しています。
署名付きURLと一時認証情報
非公開のまま特定のファイルだけを渡すには、署名付きURLを使います。許可できる操作はGET・PUT・HEAD・DELETEで、有効期限は1秒から7日(604,800秒)までです。署名はR2と通信せずにサーバー側で生成でき、ブラウザからR2へ直接アップロードさせる用途にも使えます。
署名付きURLは <ACCOUNT_ID>.r2.cloudflarestorage.com のドメインでしか使えず、カスタムドメインでは使えません。カスタムドメイン側で期限付きのアクセスを実現したいときは、WAFのHMAC検証(Proプラン以上)を使います。複数の操作をまとめて許可したい場合は、親トークンの範囲内でパスや操作を絞った一時認証情報を発行する方法もあります。ブラウザから直接読み書きさせるときは、バケットにCORSポリシーの設定も必要です。
S3からR2への移行:Super SlurperとSippy
移行ツールは2つあり、どちらもツール自体の利用料は無料です。ただし、移行中にR2へ書き込むClass A操作は課金されます。移行後はR2の保存料と操作料金が通常どおりかかり、移行元のクラウドでも読み出し(GET)や転送の料金が発生します。
- Super Slurper:移行元のバケットを一括でコピーする。100MiB未満のオブジェクトは1回のClass A操作で転送される
- Sippy:R2に無いオブジェクトが要求されたときだけ移行元からコピーする。200MiB未満は1回のClass A操作
Super Slurperは一度で切り替えたいとき、Sippyは移行元のエグレスを一度に払わず、よく読まれるファイルから段階的に移したいときに向きます。移行元がS3なら、S3側の転送料金は移行中も発生します。S3でのバケット操作や署名付きURLの手順と比べながら進めるなら、AWS S3のCLIでのバケット作成と権限設計が参考になります。
Cloudflare R2を選ぶべきでない場面
エグレス無料は強力ですが、次の条件に当てはまるならS3など他の選択肢のほうが合います。
AWS内で完結するワークロード:同じリージョン内のEC2やLambdaとS3の間の転送は無料です。R2に移すと、AWSからR2へ送るデータはAWS側でインターネット向け転送として課金されます。データを外へ配信しない分析基盤やバッチ処理では、R2の強みであるエグレス無料が効かず、節約できるのは保存単価の差に限られます。そこにAWS側の新たな転送料金が加わるので、移行前に両方の総額を試算してください。
バージョニングや細かいポリシーが前提の運用:誤削除からの復元をバージョニングに頼っている、IAMポリシーで接続元IPや条件を細かく絞っている、といった設計はR2では組めません。バケットロックとトークン権限で代替できるかを先に確かめる必要があります。
小さなファイルを大量に読む配信:公式の試算では、100KBのファイルを1日1,000万回読むと月$104.40で、その全額がClass B操作です。エグレスが無料でも操作料金は残ります。カスタムドメインとキャッシュを組み合わせ、R2に届く読み取りを減らす設計が前提です。
逆に、画像・動画・ダウンロードファイルなど外部への配信量が多く、S3の請求の大半がエグレスになっているなら、R2への移行効果は大きくなります。自社運用のS3互換ストレージも候補に入れるなら、MinIOのOSS版アーカイブ後の採用判断もあわせて検討してください。
よくある質問
Cloudflare R2の容量に上限はありますか?
バケットあたりの保存容量とオブジェクト数は無制限です。1つのオブジェクトの上限は4.995TiBで、1回のリクエストでアップロードできるのは4.995GiBまでです。
無料枠を超えるとどうなりますか?
超えた分が従量で請求されます。停止はしません。課金は100万回単位、GB-月単位で切り上げられるため、わずかな超過でも1単位分の料金がかかります。
東京リージョンを指定できますか?
都市単位の指定はできません。指定できるのは apac(アジア太平洋)などの地域ヒントで、ベストエフォートです。日本から作成すれば、Automaticでも近いリージョンが選ばれます。
アクセスキーは後から確認できますか?
Access Key IDは確認できますが、Secret Access Keyは作成直後の画面でしか表示されません。紛失したらトークンを作り直します。
wrangler devでS3互換APIを使えますか?
公式ドキュメントでは使えないと注記されていますが、wrangler 4.115.0以降では実験的なローカル対応が案内されています。安定して試すなら、ローカルではバインディング経由で操作し、本物のバケットにはバインディングの "remote": true で接続します。