Object Storage Speed Is a Front-End Problem
Developers often treat object storage as a back-end concern, but it has a direct impact on the end-user experience. Any time a request misses a cache or involves dynamic or uncacheable content, the storage service’s latency becomes the user’s latency. Compute and database layers also depend on storage, so a slow object store cascades through the entire stack. One slow image fetch or API response can undermine dozens of fast ones.
To measure real-world storage performance, Cloudflare benchmarked R2 against Amazon S3 for a simple scenario: fetching static images from public buckets. Test nodes retrieved a 1 MB file uncached from each service. The results show R2 consistently outperforming S3, with Cloudflare reporting a 20–40% edge at the 95th percentile for response time.
Benchmark Results by Region
For users in North America retrieving content from a bucket in Ashburn, Virginia (US-East), R2 was 38% faster than S3 at the 95th percentile:

Looking only at North American users, R2 beat S3 by 30% in response time. The gap comes down to connection establishment and network optimization:
| Storage Performance: Response in North America (US-East) | |
|---|---|
| 95th percentile (ms) | |
| Cloudflare R2 | 1,262 |
| Amazon S3 | 2,055 |

| Storage Performance: Connect and SSL in North America (US-East) | ||
|---|---|---|
| 95th percentile connect (ms) | 95th percentile SSL (ms) | |
| Cloudflare R2 | 32 | 59 |
| Amazon S3 | 78 | 180 |
Cloudflare’s combined TCP connect and SSL time was nearly half of Amazon’s SSL time alone. That advantage compounds in regions where ISPs already have good peering with cloud providers.
The trend holds outside North America. For EMEA, R2 beats S3 by 20% at the 95th percentile:

| Storage Performance: Response in EMEA (EU-East) | |
|---|---|
| 95th percentile (ms) | |
| Cloudflare R2 | 1,303 |
| Amazon S3 | 1,729 |
A similar pattern emerges in APAC, where objects stored in Tokyo were served roughly 1.5 times faster on R2 than on S3:
| Storage Performance: Connect and SSL in EMEA (EU-East) | ||
|---|---|---|
| 95th percentile connect (ms) | 95th percentile SSL (ms) | |
| Cloudflare R2 | 57 | 94 |
| Amazon S3 | 80 | 178 |

Cross-Region Requests
In-region performance is only one scenario. When users outside the US access content hosted in Ashburn, R2 also comes out ahead—nearly 2x faster than S3 at the 95th percentile:

| Storage Performance: Response for users outside of US connecting to US-East | |
|---|---|
| 95th percentile (ms) | |
| Cloudflare R2 | 3,224 |
| Amazon S3 | 6,387 |
That cross-region edge is notable because R2’s default setup doesn’t require picking specific datacenter locations. Instead, you provide a regional location hint, and Cloudflare stores your data within that region. This simplifies deployment but complicates direct comparisons, so for the benchmark Cloudflare pinned R2 to the same specific datacenters used for S3 to ensure an apples-to-apples test.
Test Methodology
To run the benchmark, Cloudflare used over 400 Catchpoint backbone nodes embedded in last-mile ISPs worldwide. Each node retrieved a 1 MB uncached file from R2 and S3 in Ashburn, Tokyo, and Frankfurt every 30 minutes over a four-day period. Caching was disabled on R2 to confirm that the results reflected storage performance only, not CDN benefits.
Cloudflare acknowledges that many workloads involve larger files and intends to run tests with bigger payloads in the future.
Storage Needs Compute
Object storage rarely operates in isolation. Developers combine it with compute services for full applications. Cloudflare also reran its earlier compute benchmarks, confirming that Workers remains faster than AWS Lambda@Edge and Fastly’s Compute@Edge for end-to-end performance in Rust tests:

For JavaScript tests, Workers beat both Fastly and AWS; for Rust tests, it beat Fastly. AWS only supports JavaScript on Lambda@Edge. The tests use a complex JavaScript function and a complex Rust function, run from real user browsers as part of Cloudflare’s ongoing network benchmarking:
JavaScript complex function:function testHardBusyLoop() {
let value = 0;
let offset = Date.now();
for (let n = 0; n < 15000; n++) {
value += Math.floor(Math.abs(Math.sin(offset + n)) * 10);
}
return value;
}
Rust complex function:
fn test_hard_busy_loop() -> i32 {
let mut value = 0;
let offset = Date::now().as_millis();
for n in 0..15000 {
value += (((offset + n) as f64).sin().abs() * 10.0) as i32;
}
value
}
The combination of Workers and R2 offers a simpler developer experience than competitors, with the performance measured here baked in rather than requiring manual tuning of regions or datacenters.



