Field guide

S3 compatibility is an operation checklist

Validate the client behavior you need instead of treating API compatibility as a universal yes/no promise.

Reviewed 2026-09-07 · Editorial analysis, not a performance test

Start from the application

“S3 compatible” is a useful starting point for tooling, but not a complete specification of behavior. Two services can accept familiar requests while differing in supported headers, authentication options, policy features or object lifecycle behavior. Begin with the calls your application actually makes.

Build the checklist from traces, client documentation and integration tests. Include the SDK version. A library upgrade may change checksums, signing or upload behavior without an obvious change in your application’s own code. A successful small upload does not validate every path used by a backup job or media pipeline.

A compact test matrix

Use disposable objects and check these operations independently:

  • Put and fetch a small object; verify both bytes and content type.
  • Upload a large object using the client’s multipart path, interrupt it, and inspect unfinished parts.
  • List more objects than fit in one response; verify pagination and key encoding.
  • Fetch a byte range and compare it with the source slice.
  • Attempt authorized and unauthorized access, including expired access if your design uses it.
  • Replace and delete an object, then inspect the behavior your application expects from versions and retention settings.

Do not run destructive checks against the only copy of real data. The purpose is to learn how a disposable setup behaves, not to prove safety by observing a successful happy-path request.

Compare documented gaps before testing

Cloudflare publishes an R2 S3 implementation matrix. Bunny’s current official material describes its S3 support as public preview; its existing HTTPS storage API is a different interface. Other providers’ S3-compatible endpoints still need an operation-specific review. The provider profiles link the documentation checked for this release.

The comparison’s “supported” status means a documented S3-compatible interface is offered, not that CloudOverview has verified full API parity. Preview is a separate filter state. Unknown capabilities, including object-lock status in this initial dataset, are not promoted to supported.

Permissions are part of compatibility

Record which credential signs a request, which endpoint receives it, and which permission permits it. Test a denied operation as deliberately as a permitted operation. A service accepting a signature does not by itself prove that the application’s intended authorization boundary is correct.

If the application publishes a URL, determine whether it uses the storage API endpoint, a custom domain, a CDN or an application proxy. A signed URL may be specific to one of those paths. Test access expiration and cache behavior on the exact route the end user will receive.

Leave a migration record

Keep a mapping of bucket names, object keys, metadata and public URLs. Verify checksums and object counts after a copy. Test the old and new read paths before changing the application, and define how to roll back if an operation behaves differently.

The request-cost guide explains why different client call patterns can change the bill even with identical capacity. Use S3 versus R2 for an architectural comparison, and the calculator only after the required API behavior is understood.