s3object storageapi compatibilitymultipart uploadvendor lock-in

S3-Compatible Storage Providers: What to Compare

September 2026 · 19 min read · Surya

  • The 'S3 compatible' checkbox is the least useful thing on the page
  • The five axes that actually decide an S3 compatible provider
  • For enterprise: the control plane you don't own is the risk you didn't model
  • Multi-cloud S3-compatible storage: the theory and the bill
  • Where we beat the alternatives, and the callout we owe you
  • Who should not use Storafleet for S3 compatible storage

The 'S3 compatible' checkbox is the least useful thing on the page

A developer is staring at a pricing page for an object storage provider she has never used before. The page says S3 compatible in a friendly blue font, and she is trying to figure out whether that means her existing tooling will just work, or whether she is about to spend a weekend discovering which parts of the S3 API this provider chose not to implement.

She is right to hesitate. "S3 compatible" is not a specification. There is no certification body, no conformance suite you can point at and say "this passed." What exists is a very widely implemented HTTP API with a lot of surface area, and every provider picks a different subset of it. Some of them implement enough that your code never notices. Some implement the twelve endpoints that make a demo work and quietly 501 the rest.

So what does the claim actually mean, in operational terms? It means the provider speaks the S3 wire protocol: GET, PUT, DELETE, HEAD against path-style or virtual-host-style URLs, with SigV4 request signing, and it returns XML that looks like S3's XML. That is the contract. It is a real contract and it is worth something. It is also thin enough that two providers can both honour it and behave nothing alike.

Concretely, here is the list of things that are "S3 compatible" on paper and different in practice:

  • Multipart upload limits. Minimum part size, maximum part count, whether you can re-upload a part, whether the ETag of a multipart object is even an MD5. It often is not.
  • Consistency. S3 itself is strongly consistent now. Plenty of "S3 compatible" systems are eventually consistent on overwrite and delete, which is exactly the case your backup job hits at 3am.
  • Presigned URLs. Whether they work, what clock skew they tolerate, whether they survive a proxy, whether Content-Disposition gets through.
  • Bucket naming and region semantics. Some providers reject dots in bucket names because TLS wildcard certs break. Some ignore the region entirely and some error if you send the wrong one.
  • Object lock, versioning, lifecycle rules. Frequently present in the docs, frequently partial in the implementation. Object lock in governance mode only. Lifecycle rules that fire on a schedule measured in days and not hours.
  • Error codes. The part nobody tests until production. A provider that returns 500 where S3 returns NoSuchKey will wreck your retry logic, and your retry logic is what stands between you and a duplicated dataset.

The checkbox tells you the provider read the S3 docs. It does not tell you which half they implemented. The only way to know is to run your actual workload against it, or to read the compatibility matrix that most providers bury three clicks deep and update twice a year.

This is not a knock on any particular vendor. It is a knock on the habit of treating a compatibility claim as a decision. We built Storafleet to sit on top of 50+ of these endpoints precisely because we got tired of writing the same adapter code over and over. When we connect to a new provider, we find out the hard way which parts of the API are real. You can see the list we maintain at storafleet.com/providers, and it exists because "compatible" is a starting point, not an answer.

The five axes that actually decide an S3 compatible provider

If you are comparing providers, compare these five things and ignore the checkbox. The checkbox is a filter, not a ranking. Here is the framework we use internally.

1. The API cut

Not "does it speak S3" but "which S3." Ask for the compatibility matrix. Then ask specifically about the four features that break migrations in the field: multipart upload behaviour, object versioning, server-side encryption with customer-provided keys (SSE-C), and the exact error taxonomy. If a provider cannot tell you what it returns for a missing key, that is your answer.

A worked example. You have a 400 GB dataset to move. You write a script using a generic S3 SDK. It works against the source, and against the destination it fails at hour six with a part-size rejection because the destination's minimum multipart part is larger than the source's default chunk. That is not a bug in your script. That is the API cut, and it is the single most common reason a migration stalls halfway.

2. The egress model

This is where the pricing page is least informative, and it is uninformative by omission. S3-compatible providers have wildly different egress stories. Some charge per gigabyte out. Some charge nothing for egress but charge a minimum storage commitment. Some charge nothing for egress to the public internet but charge for cross-region replication. Some have an unpublished "fair use" clause that only becomes visible when you start moving real volume.

The thing to understand: egress is not a line item, it is a business model. A provider with free egress is making a bet that your data sits still. A provider with expensive egress is making a bet that you will not leave. Neither is dishonest, but you need to know which bet you are inside.

We built Storafleet's pricing as a flat subscription with unmetered migrated bytes on every tier, including Free. That is a deliberate answer to this axis. Migrating your data is the thing you should never be scared to do, because the moment leaving is expensive, you have lost an option you did not know you were paying for.

3. Consistency

Read the docs for the words "eventually consistent." If they appear, model it. The failure is not that your code breaks. It is that your code works in testing and fails silently under load, because a PUT followed immediately by a GET returned the old object and your pipeline wrote a stale value downstream.

Test it the boring way. Write an object, read it back immediately, overwrite it, read it back immediately, delete it, list the prefix. Do that a thousand times in parallel. If it holds, good. If it does not, you know exactly where you stand before you have a dataset on the line.

4. Durability and the fine print

Every provider claims eleven nines. Almost none of them will show you the erasure coding scheme. Ask three questions: how many copies or fragments, across how many failure domains, and what happens during a rack failure. If the answer is "we replicate three times within one facility," that is a different product from one that spreads across three availability zones, and it will be priced differently, and it should be.

Also ask about deletion. Not durability of the data you have, durability of the data you deleted. Retention windows, object lock, whether a delete is a delete or a tombstone. This matters enormously the first time someone deletes the wrong prefix.

5. Operational fit

This is the axis nobody puts on a comparison table and the one that decides whether you keep using the provider in two years. Questions: Does it have a real API for the control plane, or is the console the only way to change a lifecycle rule? Can you create credentials scoped to a single bucket and prefix? Is there an audit log? Can you see per-bucket spend without exporting billing data to a spreadsheet? Does the CLI exist and does it match the console?

Operational fit is why teams end up with three providers and no idea which one is being used for what. The provider was fine. The operational story was not.

For enterprise: the control plane you don't own is the risk you didn't model

For enterprise buyers, the storage is rarely the problem. The control plane is. This is the part that surprises large teams, and it is worth being blunt about.

When you use a provider's own console, you are operating inside a system you do not own, cannot audit past what they expose, and cannot extend. That is fine when you have one cloud and one team. It stops being fine at the scale where a single team's console access is a compliance question.

Here are the failure modes we see, described as the shape of the incident rather than the incident itself:

  • The credential that outlived the person. A long-lived access key created for a migration in 2023, still valid, still used by a script nobody remembers, still scoped to the whole account. Nobody can prove who created it because the console's audit log only goes back ninety days.
  • The lifecycle rule nobody can explain. An object expires, a compliance team asks why, and the answer lives in a console UI that has been redesigned twice since the rule was written.
  • The bucket that got made public. Not by an attacker. By a well-meaning engineer who clicked the wrong toggle in a UI that has no policy guardrail, because the provider's console has no concept of "this account may not make buckets public."
  • The four clouds and the missing inventory. Data spread across three providers and one on-prem MinIO cluster, with no single place that can answer "do we have any bucket holding customer PII that is more than a year old."

None of these are storage failures. All of them are control-plane failures. They happen because the surface you operate the estate from is owned by the vendor, not by you, and it was designed for a single customer doing a single thing, not for an organisation with policies.

The corporate controls that matter at this scale are unglamorous. Central credential inventory with rotation. Named ownership per bucket. Policy that is enforced, not documented. An audit trail you control and can retain for as long as your regulator says. Per-bucket cost attribution so the finance conversation is not a guess.

We are a control plane, so obviously we think this is the right shape. But we should say what we actually are in this context: Storafleet is a control plane for object storage you already own. We never store your file contents. We connect to 50+ S3-compatible providers plus any custom endpoint, and we give you one place to browse, migrate, sync, search, and configure lifecycle, CORS, versioning, object lock and public-access settings across all of them.

Credentials are encrypted at rest with AES-256-GCM using per-namespace HKDF keys, and AWS can be connected keylessly via IAM role assumption, which means no long-lived key for the largest provider in the set. That is a real answer to the credential-outlives-the-person problem. It is not a complete answer, and the next section says why.

Multi-cloud S3-compatible storage: the theory and the bill

Multi-cloud is not a strategy. It is a bill with a strategy attached, and the strategy is usually written after the bill arrives.

The theory is elegant. Every backend speaks S3, so you write once and deploy everywhere, move data wherever it is cheapest, and you are never locked in. The theory holds up right up until you try to move a bucket.

Here is what actually happens. You have data in provider A. You want a copy in provider B for redundancy, and a working set in provider C because its egress is free and your CDN is there. You now have three problems: migration, sync, and the operations that span providers.

Migration

Migration is a one-time problem and people underestimate it every single time. A few specifics:

  • The list operation is the bottleneck, not the transfer. Listing a bucket with tens of millions of keys takes hours before a single byte moves. Pagination, prefix parallelism, and the provider's rate limits on listing all matter more than your bandwidth.
  • Small objects are the tax. A dataset of 50 million 4 KB files moves at a fraction of the throughput of a dataset of 50 files of 4 GB, and no tooling makes that go away. It is per-object overhead, all the way down.
  • Metadata does not always survive. Content-Type, custom user metadata, and storage class are the three that get quietly dropped. You will not notice until something renders as a download instead of a page.
  • Verification is the part people skip. Checksums may not be comparable across providers, because the source's ETag is an MD5 and the destination's is a multipart hash. You end up verifying by size and by re-reading, which doubles the time.

Sync

Sync is migration that never ends, and it is where the per-gigabyte pricing model gets ugly. If your provider charges for egress and your sync runs hourly, you are paying an hourly tax on data that has not changed. The fix is change detection that is cheap: comparing list output and object metadata rather than re-reading content, and scheduling that respects how fast the source actually changes.

This is the axis where the pricing model of the migration tool matters as much as the pricing model of the storage. If your tool charges per gigabyte moved, a scheduled sync is a subscription to your own data. We made migrated bytes unmetered on every tier, including Free, for exactly this reason. Our tiers differ on concurrent migration jobs and on automation, meaning scheduled sync, not on bytes.

Cross-provider operations

This is the part the theory never mentions. Once you are multi-cloud, you need to answer questions that span providers, and the S3 API gives you no help with any of them:

  • Do I have the same object in two places, and are they actually the same? Duplicate detection across providers means comparing hashes that may not be comparable, which is why we do content-aware duplicate detection rather than trusting ETags.
  • Where is this file? Global cross-bucket search across every connected endpoint, because "which of my twelve buckets has the customer export from March" is a real question with no S3-native answer.
  • What is this costing me per bucket? Cost visibility broken down per bucket, because the provider's bill is per account and that is not the granularity anyone needs.
  • Who can read this? Public-access configuration checked across the whole estate in one place, because the bucket that got made public is never in the account you are looking at.

The honest summary of multi-cloud: the API is portable, the operations are not. Speaking S3 everywhere gets you a common language. It does not get you a common control plane, a common cost model, or a common policy. Those you build, or you buy, or you accept that you have three separate estates with a shared acronym.

Where we beat the alternatives, and the callout we owe you

If your budget for this is zero, the conversation is over and rclone wins. Not in some narrow sense. It wins outright.

We are going to make our case first, and then we are going to tell you where rclone beats us, and we are not going to walk any of it back.

Our case is narrow and we will keep it narrow. Storafleet is a control plane for object storage you already own. What that buys you:

  • One console over 50+ S3-compatible providers plus any custom endpoint. Amazon S3, Cloudflare R2, Backblaze B2, Wasabi, MinIO, DigitalOcean Spaces, Oracle Cloud, IBM Cloud Object Storage, Scaleway, Linode, Vultr, Storj, IDrive e2, Hetzner. One place to browse, upload, download and search across all of them.
  • Migration and sync as first-class operations, one-time or scheduled, with unmetered migrated bytes on every tier including Free. The tiers differ on concurrent jobs and on automation.
  • Configuration across the estate in one view. Lifecycle, CORS, versioning, object lock and public-access settings, applied and inspected centrally rather than per-provider-console.
  • Duplicate detection and per-bucket cost visibility, which are the two things you cannot get from any single provider's console because they are inherently cross-provider questions.
  • Credentials encrypted at rest with AES-256-GCM under per-namespace HKDF keys, and AWS connectable keylessly via IAM role assumption.

That is the pitch. It is a real product and we are proud of it. Now the concession, and we mean this.

rclone genuinely beats us, and it beats us on dimensions that matter to a lot of people. It is free, permanently, with no account and no vendor. It supports more backends than we do, over 70, including the consumer clouds we deliberately do not touch. It mounts, which we cannot do at all. It is scriptable, so it composes with cron, systemd, CI pipelines, shell scripts and Makefiles in a way a web console never will. It runs entirely inside your own security boundary, so the credentials never leave your hardware, which is a strictly stronger answer than our encrypted database no matter how good our encryption is. And it has been maintained for over a decade, which means on the question "will this still exist in five years," rclone has a better answer than we do. We started in 2026. We are a small team. We have no published case studies and no named customers, and we are not going to invent any.

There is a second concession. Your credentials sit encrypted in our database, not on your own hardware. The encryption is real. AWS can be connected keylessly. But "the keys never left my laptop" is a stronger statement than anything we can make, and it would be dishonest to pretend otherwise.

And a third, which costs us the most. We are a console, not a command. We do not compose. If your workflow is code, a CLI fits it natively and a web UI never will. We are not going to tell you to wrap us in a headless browser. Use the binary.

If you want the short version of all of that, here it is. This is the callout, and it is the most useful paragraph in the post.

Who should not use Storafleet for S3 compatible storage

Most of this section is us telling you to use something else. That is deliberate. A control plane is a specific tool for a specific shape of problem, and if your problem is a different shape, we are overhead.

If your budget for this is zero, use rclone. The conversation is over and rclone wins. It is free forever, it has no account, and it will do the migration you are trying to do. Paying us to do what a free binary does well is not a good use of your money, and we would rather you spend it on storage.

If you need storage mounted as a filesystem, use rclone mount, Mountain Duck or ExpanDrive. We have no FUSE surface. If you want a bucket to appear in Finder or Explorer as a drive letter, we cannot do it. Not "we do it badly." We do not do it. This is a hard boundary and it is not on the roadmap as a maybe.

If you need Google Drive, Dropbox, OneDrive, Box, SFTP or WebDAV, use rclone or MultCloud. We connect the S3-compatible family and any custom S3 endpoint, and nothing else. If the job is Drive-to-bucket, we are the wrong tool and you should stop reading and go install rclone.

If your credentials must never leave hardware you control, use rclone. Or, if it is AWS only, use our IAM role assumption connect, which means no long-lived key exists at all. But for a blanket "no credential leaves my network" requirement, rclone running on your own box is the correct answer and our encrypted database is not.

If everything lives in one cloud and always will, use that provider's own console. It is free, it is authoritative, and it will always know about that provider's newest features before we do. A control plane earns its keep across multiple providers. Across one, it is a layer of indirection.

If your workflow is entirely code and always will be, use a CLI. A binary composes with cron, systemd, CI pipelines and Makefiles. A console does not, and never will, and no amount of API access changes the fact that the thing you want to type is a command.

Now the other side, briefly, because a post that only says who should not use us is not an honest post either.

Use Storafleet if you have an estate rather than a bucket. If you have data in two or three providers, if you need to know what is where, if you need duplicate detection and per-bucket cost visibility and lifecycle rules applied across all of it, if you want scheduled sync without a per-gigabyte meter on the migration, and if you want the credentials and the policy in one auditable place. That is the shape we were built for. That is what a control plane is for.

And if you are not sure, run the test we would run. Count your providers. Count the buckets. Try to answer, right now, without opening four consoles, which bucket holds your oldest copy of customer data and whether it is public. If that took you more than a minute, you have the problem we solve. If it took you five seconds because there is one bucket in one account, you do not, and the provider's console is free.

Your storage estate deserves a control plane.

Join the DevOps teams and founders who run every cloud's buckets from one control plane.

Free plan  ·  No credit card  ·  50+ cloud providers  ·  Cancel any time