R2ローカルアップロードによるグローバルアップロード性能の向上
CloudflareはR2オブジェクトストレージに「Local Uploads」機能をオープンベータで公開し、クライアントに近い場所にデータを一時保存してから非同期でバケットにコピーすることで、グローバルなアップロード性能を最大75%向上させると発表した。
キーポイント
Local Uploadsの仕組み
クライアントに近いストレージロケーションにデータを最初に書き込み、その後非同期でバケットの所在地にコピーすることで、アップロードを高速化し、データは即座にアクセス可能で強い一貫性を保つ。
性能向上の実証
バケットと異なるリージョンからのアップロードリクエストで、Time to Last Byte(TTLB)が最大75%削減され、グローバルなアップロード性能が大幅に向上することを顧客テストと合成ベンチマークで確認した。
実装の容易さ
Cloudflareダッシュボードのバケット設定から有効化できるほか、既存のバケットに対して単一のWranglerコマンドでLocal Uploadsを有効にすることが可能である。
グローバルネットワークの活用
R2はCloudflareのグローバルネットワーク上に構築されたオブジェクトストレージであり、Local Uploadsにより読み取りだけでなく書き込みも世界中どこからでも高速化される。
即時アクセス性
オブジェクトは初期書き込み完了後すぐにアクセス可能で、バックグラウンドレプリケーションが完了するのを待つ必要はない。
使用制限
Local Uploadsは管轄制限(EU、FedRAMPなど)が有効なバケットでは利用できない。
Local Uploadsの非同期レプリケーション処理
アップロードされたオブジェクトデータはクライアント近くに書き込まれ、バックグラウンドでバケットのリージョンにコピーされる。このコピージョブはレプリケーションタスクと呼ばれ、Cloudflare Queuesを使用して非同期に処理される。
影響分析・編集コメントを表示
影響分析
この発表は、グローバルに分散したユーザーやデバイスからのデータ収集を必要とするアプリケーションにとって重要な進展である。特にメディアコンテンツのアップロードやIoTデバイスからのテレメトリ収集など、地理的な遅延が課題となるユースケースで実用的な価値を提供する。Cloudflareのグローバルネットワークインフラを活用したこの機能は、エッジコンピューティングとクラウドストレージの統合的な進化を示している。
編集コメント
グローバルなデータ収集ワークフローのボトルネックを解消する実用的なソリューションで、特にAI/MLパイプラインにおける大規模データ収集や分散トレーニングデータの管理に応用可能性が高い。
R2ローカルアップロードでグローバルアップロード性能を向上
Frank Chen
Rahul Suresh
Anni Wang
本日、R2のローカルアップロード機能をオープンベータとしてローンチします。ローカルアップロードを有効にすると、オブジェクトデータはまずクライアントに近いストレージロケーションに自動的に書き込まれ、その後、非同期でバケットが存在する場所にコピーされます。データは即座にアクセス可能で、強整合性を維持します。アップロードが高速化され、データはグローバルに感じられるようになります。
多くのアプリケーションにとって、パフォーマンスはグローバルである必要があります。例えば、異なる地域からメディアコンテンツをアップロードするユーザーや、世界中からログやテレメトリを送信するデバイスなどです。しかし、データはどこかに存在しなければならず、それは遠方からのアップロードがバケットに到達するまで長距離を移動しなければならないことを意味します。
R2は、Cloudflareのグローバルネットワーク上に構築されたオブジェクトストレージです。すぐに使える状態で、強整合性とゼロエグレス料金を維持しながら、オブジェクトデータをグローバルに自動的にキャッシュし、どこからでも高速な読み取りを実現します。これは、S3 API、Workersバインディング、またはプレーンなHTTPのいずれを使用している場合でも、バックグラウンドで行われます。そして今回のローカルアップロードにより、読み取りと書き込みの両方を世界中のどこからでも高速に行えるようになりました。
このデモでローカルアップロードの利点を実際に試してみてください。
試してみる準備はできていますか?Cloudflareダッシュボードのバケット設定で、または既存のバケットに対して単一のWranglerコマンドで、ローカルアップロードを有効にできます。
npx wrangler r2 bucket local-uploads enable [BUCKET]
グローバルアップロードの総リクエスト時間が75%短縮
ローカルアップロードは、アップロードリクエスト(PutObject、UploadPartなど)を高速化します。顧客とのプライベートベータテストと合成ベンチマークの両方で、バケットとは異なる地域からのアップロードリクエストにおいて、最終バイト到達時間(TTLB)が最大75%短縮されることが確認されました。これらの結果では、TTLBはR2がアップロードリクエストを受信してから200応答を返すまでの時間として測定されています。
合成テストでは、クロスリージョンアップロードワークフローをシミュレートする合成ワークロードを使用して、ローカルアップロードの影響を測定しました。北米西部にテストクライアントをデプロイし、アジア太平洋地域をロケーションヒントとして設定したR2バケットを構成しました。クライアントは、5MBサイズのオブジェクトをアップロードするために、30分間にわたって毎秒約20回のPutObjectリクエストを実行しました。
以下のグラフは、これらのリクエストのp50(中央値)TTLBメトリクスを比較し、アップロードリクエスト時間の違いを示しています。まずローカルアップロードなし(TTLB約2秒)、次にローカルアップロード有効(TTLB約500ミリ秒)の場合です:
仕組み:距離の問題
ローカルアップロードがどのようにアップロードリクエストを改善できるかを理解するために、まずR2の動作を見てみましょう。R2のアーキテクチャは、以下の複数のコンポーネントで構成されています:
R2ゲートウェイワーカー:認証とルーティングロジックを処理するすべてのAPIリクエストのエントリポイント。Cloudflare Workersを介してCloudflareのグローバルネットワーク全体にデプロイされます。
Durable Objectメタデータサービス:オブジェクトメタデータ(例:オブジェクトキー、チェックサム)を保存および管理するために使用される、Durable Objects上に構築された分散レイヤー。
分散ストレージインフラストラクチャ:暗号化されたオブジェクトデータを永続的に保存する基盤インフラストラクチャ。
ローカルアップロードなしの場合、バケットにオブジェクトをアップロードすると次のことが起こります:リクエストはまず、ユーザーに近いR2ゲートウェイによって受信され、認証されます。その後、クライアントがオブジェクトデータのバイトをストリーミングするにつれて、データは暗号化され、バケットが配置されている地域のストレージインフラストラクチャに書き込まれます。これが完了すると、ゲートウェイはメタデータサービスに接続してオブジェクトメタデータを公開し、コミットされた後に成功応答をクライアントに返します。
クライアントとバケットが別々の地域にある場合、リクエストが移動しなければならない距離が長くなるため、オブジェクトデータのバイトをアップロードする過程でより多くの変動が生じる可能性があります。これにより、アップロードが遅くなったり、信頼性が低下したりする可能性があります。
ローカルアップロードが有効でない状態で、北米東部から東欧のバケットにアップロードするクライアント。
さて、ローカルアップロードが有効なバケットにアップロードリクエストを行う場合、以下の2つのケースが処理されます:
クライアントとバケットリージョンが同じ地域にある場合
クライアントとバケットリージョンが異なる地域にある場合
最初のケースでは、R2は通常のフローに従い、オブジェクトデータはバケットのストレージインフラストラクチャに書き込まれます。2番目のケースでは、R2はオブジェクトメタデータをバケットの地域に公開しつつ、クライアント地域にあるストレージインフラストラクチャに書き込みます。
重要な点は、オブジェクトは最初の書き込みが完了した直後にアクセス可能になることです。バックグラウンドでのレプリケーションが完了するのを待つことなくオブジェクトを読み取ることができ、レプリケーションプロセス全体を通じてアクセス可能なままです。
ローカルアップロードが有効な状態で、北米東部から東欧のバケットにアップロードするクライアント。
これは管轄制限のないバケット向けであり、管轄制限(例:EU、FedRAMP)が有効なバケットではローカルアップロードは利用できないことに注意してください。
ローカルアップロードを使用するタイミング
ローカルアップロードは、バケットが存在する地域とは異なる地理的地域から発信される多数のアップロードリクエストを受信するワークロード向けに構築されています。この機能は、以下の場合に理想的です:
ユーザーが世界中に分散している
アプリケーションにとってアップロードのパフォーマンスと信頼性が重要である
バケットのプライマリロケーションを変更せずに書き込みパフォーマンスを最適化したい
読み取りおよび書き込みリクエストがどこから開始されているかの地理的分布を理解するには、Cloudflareダッシュボードにアクセスし、R2バケットのメトリクスページに移動して、「地域別リクエスト分布」グラフを表示してください。
ローカルアップロードの構築方法
ローカルアップロードでは、オブジェクトデータはクライアントに近い場所に書き込まれ、その後、バックグラウンドでバケットのリージョンにコピーされます。このコピージョブをレプリケーションタスクと呼びます。
これらのレプリケーションタスクを考慮して、非同期処理コンポーネントが必要となりました。これはCloudflare Queuesの優れたユースケースとなる傾向があります。キューを使用することで、レプリケーションタスクを処理する速度を制御でき、リトライやデッドレターキューなどの組み込みの障害処理機能を提供します。この場合、R2はストレージリージョンごとに複数のキューにレプリケーションタスクを分散させます。
メタデータの公開とレプリケーションのスケジューリング
ローカルアップロードが有効なオブジェクトのメタデータを公開する際、以下の3つの操作をアトミックに実行します:
オブジェクトメタデータを保存する
どのレプリケーションがまだ実行される必要があるかを追跡する保留中のレプリカキーを作成する
タイムスタンプでキー付けされたレプリケーションタスクマーカーを作成する(このマーカーはタスクをキューに送信するタイミングを制御します)
保留中のレプリカキーには、完全なレプリケーションプランが含まれています:レプリケーションタスクの数、読み取り元のソースロケーション、書き込み先の宛先ロケーション、レプリケーションモードと優先度、およびレプリケーション成功後にソースを削除するかどうか。
これにより、オブジェクトデータの移動方法に柔軟性が得られます。例えば、長い地理的距離をまたいだデータ移動はコストがかかります。すべてのレプリカを並列処理することで可能な限り速く移動しようとするかもしれませんが、これはコストが増大し、ネットワークインフラストラクチャに負荷をかけます。代わりに、まず1つのクロスリージョンレプリケーションを作成し、その後、宛先リージョン内でローカルに複製することにより、クロスリージョンデータ移動の回数を最小限に抑えます。
原文を表示
Improve global upload performance with R2 Local Uploads
Frank Chen
Rahul Suresh
Anni Wang
Today, we are launching Local Uploads for R2 in open beta. With Local Uploads enabled, object data is automatically written to a storage location close to the client first, then asynchronously copied to where the bucket lives. The data is immediately accessible and stays strongly consistent. Uploads get faster, and data feels global.
For many applications, performance needs to be global. Users uploading media content from different regions, for example, or devices sending logs and telemetry from all around the world. But your data has to live somewhere, and that means uploads from far away have to travel the full distance to reach your bucket.
R2 is object storage built on Cloudflare's global network. Out of the box, it automatically caches object data globally for fast reads anywhere — all while retaining strong consistency and zero egress fees. This happens behind the scenes whether you're using the S3 API, Workers Bindings, or plain HTTP. And now with Local Uploads, both reads and writes can be fast from anywhere in the world.
Try it yourself in this demo to see the benefits of Local Uploads.
Ready to try it? Enable Local Uploads in the Cloudflare Dashboard under your bucket's settings, or with a single Wrangler command on an existing bucket.
npx wrangler r2 bucket local-uploads enable [BUCKET]
75% lower total request duration for global uploads
Local Uploads makes upload requests (i.e. PutObject, UploadPart) faster. In both our private beta tests with customers and our synthetic benchmarks, we saw up to 75% reduction in Time to Last Byte (TTLB) when upload requests are made in a different region than the bucket. In these results, TTLB is measured from when R2 receives the upload request to when R2 returns a 200 response.
In our synthetic tests, we measured the impact of Local Uploads by using a synthetic workload to simulate a cross-region upload workflow. We deployed a test client in Western North America and configured an R2 bucket with a location hint for Asia-Pacific. The client performed around 20 PutObject requests per second over 30 minutes to upload objects of 5 MB size.
The following graph compares the p50 (or median) TTLB metrics for these requests, showing the difference in upload request duration — first without Local Uploads (TTLB around 2s), and then with Local Uploads enabled (TTLB around 500ms):
How it works: The distance problem
To understand how Local Uploads can improve upload requests, let’s first take a look at how R2 works. R2's architecture is composed of multiple components including:
R2 Gateway Worker: The entry point for all API requests that handles authentication and routing logic. It is deployed across Cloudflare's global network via Cloudflare Workers.
Durable Object Metadata Service: A distributed layer built on Durable Objects used to store and manage object metadata (e.g. object key, checksum).
Distributed Storage Infrastructure: The underlying infrastructure that persistently stores encrypted object data.
Without Local Uploads, here’s what happens when you upload objects to your bucket: The request is first received by the R2 Gateway, close to the user, where it is authenticated. Then, as the client streams bytes of the object data, the data is encrypted and written into the storage infrastructure in the region where the bucket is placed. When this is completed, the Gateway reaches out to the Metadata Service to publish the object metadata, and it returns a success response back to the client after it is committed.
If the client and the bucket are in separate regions, more variability can be introduced in the process of uploading bytes of the object data, due to the longer distance that the request must travel. This could result in slower or less reliable uploads.
A client uploading from Eastern North America to a bucket in Eastern Europe without Local Uploads enabled.
Now, when you make an upload request to a bucket with Local Uploads enabled, there are two cases that are handled:
The client and the bucket region are in the same region
The client and the bucket region are in different regions
In the first case, R2 follows the regular flow, where object data is written to the storage infrastructure for your bucket. In the second case, R2 writes to the storage infrastructure located in the client region while still publishing to the object metadata to the region of the bucket.
Importantly, the object is immediately accessible after the initial write completes. It remains accessible throughout the entire replication process — there's no waiting period for background replication to finish before the object can be read.
A client uploading from Eastern North America to a bucket in Eastern Europe with Local Uploads enabled.
Note that this is for non-jurisdiction restricted buckets, and Local Uploads are not available for buckets with jurisdiction restriction (e.g. EU, FedRAMP) enabled.
When to use Local Uploads
Local uploads are built for workloads that receive a lot of upload requests originating from different geographic regions than where your bucket is located. This feature is ideal when:
Your users are globally distributed
Upload performance and reliability is critical to your application
You want to optimize write performance without changing your bucket's primary location
To understand the geographic distribution of where your read and write requests are initiated, you can visit the Cloudflare Dashboard, and go to your R2 bucket’s Metrics page and view the Request Distribution by Region graph.
How we built Local Uploads
With Local Uploads, object data is written close to the client and then copied to the bucket's region in the background. We call this copy job a replication task.
Given these replication tasks, we needed an asynchronous processing component for them, which tends to be a great use case for Cloudflare Queues. Queues allow us to control the rate at which we process replication tasks, and it provides built-in failure handling capabilities like retries and dead letter queues. In this case, R2 shards replication tasks across multiple queues per storage region.
Publishing metadata and scheduling replication
When publishing the metadata of an object with Local Uploads enabled, we perform three operations atomically:
Store the object metadata
Create a pending replica key that tracks which replications still need to happen
Create a replication task marker keyed by timestamp, which controls when the task should be sent to the queue
The pending replica key contains the full replication plan: the number of replication tasks, which source location to read from, which destination location to write to, the replication mode and priority, and whether the source should be deleted after successful replication.
This gives us flexibility in how we move an object's data. For example, moving data across long geographical distances is expensive. We could try to move all the replicas as fast as possible by processing them in parallel, but this would incur greater cost and pressure the network infrastructure. Instead, we minimize the number of cross-regional data movements by first creating one replica in the target bucket region, and then use this local copy to create additional replicas within the bucket region.
A background process periodically scans the replication task markers and sends them to one of the queues associated with the destination storage region. The markers guarantee at-least-once delivery to the queue — if enqueueing fails or the process crashes, the marker persists and the task will be retried on the next scan. This also allows us to process replications at different times and enqueue only valid tasks. Once a replication task reaches a queue, it is ready to be processed.
Asynchronous replication: Pull model
For the queue consumer, we chose a pull model where a centralized polling service consumes tasks from the regional queues and dispatches them to the Gateway Worker for execution.
Here's how it works:
Polling service pulls from a regional queue: The consumer service polls the regional queue for replication tasks. It then batches the tasks to create uniform batch sizes based on the amount of data to be moved.
Polling service dispatches to Gateway Worker: The consumer service sends the replication job to the Gateway Worker.
Gateway Worker executes replication: The worker reads object data from the source location, writes it to the destination, and updates metadata in the Durable Object, optionally marking the source location to be garbage collected.
Gateway Worker reports result: On completion, the worker returns the result to the poller, which acknowledges the task to the queue as completed or failed.
By using this pull model approach, we ensure that the replication process remains stable and efficient. The service can dynamically adjust its pace based on real-time system health, guaranteeing that data is safely replicated across regions.
Local Uploads is available now in open beta. There is no additional cost to enable Local Uploads. Upload requests made with this feature enabled incur the standard Class A operation costs, same as upload requests made without Local Uploads.
To get started, visit the Cloudflare Dashboard under your bucket's settings and look for the Local Uploads card to enable, or simply run the following command using Wrangler to enable Local Uploads on a bucket.
npx wrangler r2 bucket local-uploads enable [BUCKET]
Enabling Local Uploads on a bucket is seamless: existing uploads will complete as expected and there’s no interruption to traffic.
For more information, refer to the Local Uploads documentation. If you have questions or want to share feedback, join the discussion on our Developer Discord.

関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み