Cloudflare has launched Local Uploads for R2 in open beta, introducing a groundbreaking approach to object storage that dramatically improves upload performance for globally distributed applications. This feature enables object data to be written to a storage location close to the client first, then asynchronously copied to the bucket's primary region, delivering up to 75% reduction in upload request duration.
The Global Performance Challenge
For applications serving users worldwide, performance must be consistent regardless of geographic location. Consider users uploading media content from different regions, or IoT devices sending logs and telemetry data from around the globe. The fundamental challenge is that data must reside somewhere specific, meaning uploads from distant locations must traverse significant network distances to reach the destination bucket.
Traditionally, object storage systems force this tradeoff: your data lives in one region, and users far from that region experience slower uploads. This creates a performance penalty that's particularly painful for write-heavy workloads with geographically dispersed users.
How R2 Solves the Distance Problem
R2 is object storage built on Cloudflare's global network, designed from the ground up for worldwide performance. Out of the box, R2 automatically caches object data globally for fast reads anywhere while maintaining strong consistency and zero egress fees. Whether accessed via the S3 API, Workers Bindings, or plain HTTP, this global caching happens transparently behind the scenes.
Local Uploads extends this global-first approach to writes. When enabled, object data is automatically written to storage infrastructure close to the client first, then asynchronously replicated to where the bucket actually lives. Critically, the data becomes immediately accessible and remains strongly consistent throughout the entire process—there's no waiting period for background replication before objects can be read.
Impressive Performance Improvements
The performance gains are substantial. In both private beta testing with customers and synthetic benchmarks, Cloudflare observed up to 75% reduction in Time to Last Byte (TTLB) when upload requests originated from different regions than the bucket location.
In controlled synthetic tests, Cloudflare deployed a test client in Western North America uploading to an R2 bucket configured with a location hint for Asia-Pacific. The client performed approximately 20 PutObject requests per second over 30 minutes, uploading 5 MB objects.
Without Local Uploads, the median TTLB hovered around 2 seconds. With Local Uploads enabled, this dropped to approximately 500 milliseconds—a 75% improvement. This dramatic reduction translates directly to better user experience and higher application throughput.
Understanding the Technical Architecture
To appreciate how Local Uploads achieves these gains, it's helpful to understand R2's underlying architecture. The system comprises several key components:
The R2 Gateway Worker serves as the entry point for all API requests, handling authentication and routing logic. Deployed globally via Cloudflare Workers, it sits at the edge closest to users.
The Durable Object Metadata Service is a distributed layer built on Durable Objects that stores and manages object metadata, including object keys, checksums, and other attributes.
The Distributed Storage Infrastructure provides the underlying persistent storage for encrypted object data.
Without Local Uploads, uploads follow a straightforward path: the Gateway receives and authenticates the request near the user, but as the client streams object data, it's encrypted and written directly to storage infrastructure in the bucket's designated region. Once complete, the Gateway publishes metadata to the Metadata Service and returns success to the client.
This traditional flow introduces latency when the client and bucket are geographically separated. The variability and distance of the network path while streaming data can result in slower and less reliable uploads.
Local Uploads in Action
With Local Uploads enabled, R2 intelligently handles two scenarios. When the client and bucket are in the same region, the system follows the standard flow, writing directly to the bucket's storage infrastructure. When they're in different regions, however, R2 writes to storage infrastructure in the client's region while still publishing metadata to the bucket's region.
This approach provides the best of both worlds: fast local writes with immediate global accessibility. The object is fully accessible as soon as the initial write completes—users don't wait for background replication. Throughout the replication process, the object remains available and strongly consistent.
For non-jurisdiction-restricted buckets, this works seamlessly. Note that Local Uploads are not available for buckets with jurisdiction restrictions like EU or FedRAMP enabled, where data must remain within specific geographic boundaries.
Ideal Use Cases
Local Uploads excel in specific scenarios. The feature is purpose-built for workloads receiving many upload requests from different geographic regions than the bucket's location. This makes it ideal when:
Users are globally distributed across multiple continents and regions.
Upload performance and reliability are critical to application functionality and user experience.
You want to optimize write performance without changing your bucket's primary location or restructuring your storage architecture.
To understand whether Local Uploads would benefit your workload, check the Request Distribution by Region graph on your R2 bucket's Metrics page in the Cloudflare Dashboard. This visualization shows where read and write requests originate, helping identify geographic mismatches between users and bucket location.
The Replication Architecture
Behind the scenes, Local Uploads leverages Cloudflare's infrastructure to efficiently manage data replication. When object data is written locally, a replication task is created and processed asynchronously.
Cloudflare Queues provides the foundation for this asynchronous processing. Queues allow control over task processing rates and provide built-in failure handling capabilities including retries and dead letter queues. R2 shards replication tasks across multiple queues per storage region for scale and resilience.
When publishing object metadata with Local Uploads enabled, three operations occur atomically: storing the object metadata, creating a pending replica key tracking required replications, and creating a replication task marker keyed by timestamp.
The pending replica key contains the complete replication plan: the number of tasks, source and destination locations, replication mode and priority, and whether the source should be deleted after successful replication.
This architecture provides flexibility in data movement. Rather than immediately moving data across long geographic distances—which is expensive and stressful on network infrastructure—the system can optimize replication paths. For example, creating one replica in the target bucket region first, then using that local copy to create additional replicas within the region minimizes costly cross-regional transfers.
Pull-Based Processing Model
For queue consumption, R2 employs a pull model where a centralized polling service consumes tasks from regional queues and dispatches them to Gateway Workers for execution.
The polling service pulls replication tasks from regional queues and batches them based on data volume to create uniform batch sizes. It then dispatches replication jobs to Gateway Workers.
Gateway Workers execute the actual replication: reading object data from the source location, writing to the destination, and updating metadata in Durable Objects. Optionally, they mark the source location for garbage collection. Finally, workers report results back to the poller, which acknowledges task completion or failure to the queue.
This pull-based approach ensures stability and efficiency. The system can dynamically adjust its pace based on real-time system health, guaranteeing safe data replication across regions without overwhelming infrastructure.
Getting Started
Local Uploads is available now in open beta. There's no additional cost to enable the feature—upload requests made with Local Uploads incur the same standard Class A operation costs as requests without it.
To get started, visit your bucket's settings in the Cloudflare Dashboard and look for the Local Uploads card to enable it. Alternatively, run a simple Wrangler command:
npx wrangler r2 bucket local-uploads enable [BUCKET]
Enabling Local Uploads on an existing bucket is seamless. Existing uploads will complete as expected with no interruption to traffic. The transition is completely transparent to applications and users.
For applications requiring global upload performance, Local Uploads represents a significant leap forward. By intelligently writing data close to users while maintaining strong consistency and immediate accessibility, R2 delivers both the performance of edge storage and the simplicity of centralized object storage.
Source: Improve global upload performance with R2 Local Uploads - Cloudflare Blog