What S3 latency testing actually measures

S3 latency testing measures how long an application takes to complete object-storage operations under realistic network, region, authentication, and concurrency conditions. The useful result is not one nearly perfect number from a speed-test website; it is a distribution of request timings for the exact operation that matters to your platform, such as a 1 KiB metadata lookup, a 10 MiB upload, a multipart part transfer, or the first byte of a ranged download. AWS documentation includes guidance on measuring network latency to an AWS Region before deployment, but that measurement establishes the network floor rather than the complete S3 service time. For a B2B data plane, test both control-path operations and bulk-data paths because authentication, request parsing, service processing, and transfer time contribute differently to each request. Results should be recorded from the production client location, not from a convenient laptop close to an AWS edge point. The practical objective is to identify whether latency, throughput, error rates, or egress cost will determine the storage design.

Also worth reading: How Do You Measure and Reduce Cross-Cloud Data Plane Latency for Object Storage in 2026? · S3 cross region replication pricing 2026: what does CRR actually cost on AWS and how should platform teams budget it? · How Should Platform Teams Design S3-Compatible Object Storage in 2026?

Build a representative test before collecting numbers

A defensible test begins with a workload specification that records Region, source network, protocol, payload size, object count, concurrency, authentication mode, and expected production duration. Select at least two AWS Regions and include the incumbent location as a baseline, but choose Regions based on users, compute, compliance boundaries, and disaster-recovery requirements rather than advertised ping alone. Use a small set of common sizes: 1 KiB for metadata-like reads, 1 MiB for ordinary application objects, 64 MiB or 100 MiB for larger files, and a multipart size for bulk ingestion. Keep TLS enabled and use SigV4 or the AWS SDK because testing an anonymous public bucket measures a different system. Run warm-up requests first, then collect a steady sample long enough to expose variability rather than a brief favorable interval.

Test dimensionSmall object requestBulk transferMultipart workload
Representative size1 KiB-1 MiB10 MiB-1 GiB8-100 MiB per part
Primary metricp50 and p95 latencySustained throughputCompletion time and retry rate
Initial thresholdp95 under 100 msAt least 90% of link target99% completion without throttling
Useful sample10,000 requestsAt least 10 minutesAt least 1,000 parts or 1 hour
Common confoundWarm cachesTCP ramp-upConcurrency and part scheduling
The thresholds in this table are engineering starting points, not AWS service-level guarantees. Teams with interactive APIs may require a 50 ms p95 at the application boundary, while asynchronous analytics workloads may accept 200 ms if requests are pipelined. Replace those defaults with an explicit user-facing objective before testing, otherwise the exercise can produce a precise answer to an unimportant question. The test client should also report DNS resolution, TCP or QUIC connection establishment, TLS setup, time to first byte, total duration, throughput, retries, and HTTP status codes separately. That separation helps distinguish a slow path from credential lookup, SDK retry behavior, service throttling, or application queueing.

Execute the test without measuring your own application accidentally

Run the benchmark from the same subnet, region, operating system, and runtime that will issue production S3 requests. An EC2 client in the destination AWS Region can expose storage processing time, but it can conceal consumer internet latency and may be unusually favorable for cross-Availability-Zone traffic. A remote client provides a more realistic hybrid-cloud result, while an on-premises host captures corporate proxy, firewall, routing, and WAN behavior. For each location, pin the SDK to a specific S3 Regional endpoint and record the resolved endpoint IP addresses; disabling retries can reveal raw behavior, but production testing must repeat with SDK defaults because retries are part of actual completion time. Avoid placing the load generator and storage client behind the same constrained egress connection if the goal is to measure S3 independently.

Use concurrent workers rather than serial requests when the application will operate concurrently, but increase concurrency in controlled stages such as 1, 8, 32, 128, and 256 workers. Each stage should run long enough to distinguish connection setup from steady-state performance, preferably 5-15 minutes, and should record completed operations, failed operations, transferred bytes, and 5xx responses. A sequential transfer is appropriate only for a genuinely serial pipeline. For uploads, distinguish PutObject from multipart upload and include the create, upload, and complete phases. For downloads, distinguish a whole-object GET from a ranged read because a range request can benefit from different cache and network behavior. If a CDN fronts the content, test S3 origin performance and CDN-delivered performance as separate systems.

Interpret latency, throughput, and failures together

Median latency answers only whether the typical request was fast; percentiles reveal whether users experienced tail delays. Report p50, p95, p99, and maximum latency for each operation, but do not publish a p99 calculated from a sample too small to contain at least 100 observations beyond the target percentile. A p50 of 40 ms with a p95 of 180 ms and a 0.2% retry rate presents a different production problem from a steady p50 of 60 ms with no failures. Throughput should be expressed as MiB per second per worker and aggregate MiB per second, then compared with the capacity available on the source link. Latency and throughput can trade off: increasing concurrency may raise aggregate throughput while worsening queueing latency, and reducing concurrency may improve individual response time while limiting the application’s ingestion capacity.

Use service and application metrics to locate the delay. DNS and TLS setup can dominate small requests, connection limits can stall concurrency, and SDK retries can convert a short transient error into a multi-second completion time. HTTP 503 responses require investigation rather than automatic acceptance as “normal cloud behavior”; common causes include throttling, connection reuse defects, or overloaded dependencies, although the response body and AWS service metrics should determine the actual cause. A client-side timeout is not proof that S3 exceeded an SLA because the timeout may occur in DNS, a proxy, the network, or the client itself. Repeat suspect tests from a second network and against a known-good AWS compute client. If only one path is slow, the storage Region may not be the main issue.

Compare Regions, clouds, and hybrid designs fairly

The best Region is rarely the one with the lowest empty-network ping. Compare end-to-end S3 request duration, bulk throughput, availability, data-transfer cost, data residency, service compatibility, and operational complexity together. For example, a Region with 85 ms p95 reads may be preferable to one with 55 ms if it avoids a cross-cloud processing layer or halves transfer charges for a high-volume workload. Cross-cloud object gateways and data-plane SaaS can add policy checks, encryption, indexing, replication, or protocol translation that must be included in the test; do not attribute the complete gateway latency to the underlying S3 request. Run the same payload and client configuration through each option, and label origin-only, gateway-inclusive, and end-user measurements clearly.

Decision criterionAWS S3 Region testR2 or another object storeCross-cloud data-plane gateway
Small-request resultDirect S3 p50, p95, p99Repeat identical object operationsInclude gateway and policy overhead
Bulk transferDirect connection throughputProvider-specific protocol behaviorInclude fan-out and transformation
Data movementStandard S3 and AWS transfer pathsCloudflare-specific transfer conditionsProvider-to-provider replication and egress
Main strengthBroad AWS integration and Region choicePotentially favorable public egress economicsOne interface across multiple backends
Main riskRegion distance and AWS service chargesFeature, residency, and support differencesAdded failure modes and cost layers
Claims such as “99% cheaper egress” require verification for the tested provider, date, source Region, destination, and product configuration. Cloudflare has marketed R2 around reduced or zero public egress charges under stated conditions, while AWS S3 pricing can become expensive when data repeatedly leaves AWS. Savings are not automatic: retrievals, operations, storage classes, inter-Region transfers, gateway processing, internet transit, and replication may carry charges. As of 26 September 2026, teams should obtain current price-list records and model them with measured monthly traffic rather than relying on a headline percentage from an individual comparison.

Avoid common benchmarking errors

One common error is using ICMP ping as the result. ICMP may help identify a rough path characteristic, but it does not execute TLS, authenticate an S3 request, process an HTTP request, or transfer an object. Another error is testing one cached object and generalizing the result to millions of objects. Repetition can reveal SDK connection reuse, while randomized object names better approximate production access patterns. Do not compare a first multipart upload against a resumed transfer, or test acceleration only after TCP has already converged. Compression, checksums, encryption, and application serialization should remain consistent across options if they exist in production.

Another error is running too little traffic for too little time. A ten-request test can be corrupted by DNS, TLS, routing changes, or a transient service event; a stress test can instead overwhelm the client and say little about normal operation. Separate baseline, production-load, peak-load, and fault-recovery phases, and preserve raw measurements for later comparison. Avoid changing Region, SDK version, operating system, packet size, or source network in the middle of a run without labeling the change. Finally, do not delete and recreate every test object at full scale, because cleanup can create a second storage workload and inadvertently test the wrong path. Use lifecycle expiration or a controlled cleanup period, while ensuring the benchmark does not violate lifecycle or retention policies.

Decide whether to migrate, adjust, or keep the current Region

Act on the data when several runs show that a storage decision conflicts with a documented requirement. If direct S3 p95 exceeds the application target by more than 20% in two or more locations, investigate the network, Region distance, gateway, or concurrency before changing vendors. If throughput is below 80% of the available link target while latency remains low, inspect stream sizing, SDK buffers, multipart concurrency, CPU utilization, and packet loss. For high-volume migration, compare the cost of leaving data in place, moving it to a nearby Region, introducing a read-through gateway, or changing the application’s compute location. A slower storage service can still be the rational choice when it removes repeated cross-cloud processing or reduces network charges enough to offset the latency difference.

Set a review date rather than treating one benchmark as permanent infrastructure truth. Internet routing, provider capacity, software defaults, and prices can change after the test, so repeat the benchmark after a major SDK upgrade, network change, Region launch, or contract negotiation. Retain Region, endpoint, client version, object sizes, concurrency, and percentile results with the report; without those details, a future reader cannot reproduce the conclusion. For a platform team managing multiple object stores, automate the test as a periodic canary and alert on p95 regression, throughput loss, and error-rate changes. The best outcome is not a universally fast storage layer, but a documented data plane whose latency and cost fit the workloads it actually serves.