
Object versioning is the feature underneath a claim that gets made constantly and understood precisely far less often: "you can recover an accidentally deleted or overwritten file." AWS's own documentation describes the mechanism directly, S3 Versioning lets you "keep multiple versions of an object in one bucket so that you can restore objects that are accidentally deleted or overwritten." The mechanics behind that, what actually happens on delete, how much it actually costs to keep every version, and the one feature it quietly enables, are worth understanding on their own terms, not just as a bullet point on a feature comparison chart.
TL;DR:
AWS's own description is the cleanest starting point: S3 Versioning lets you "keep multiple versions of an object in one bucket," specifically so that "objects that are accidentally deleted or overwritten" can be restored. The mechanism assigns a unique, S3-generated version ID to each stored version of an object, and critically, versioning is opt-in: AWS states plainly that "by default, your bucket is unversioned." Nothing about this protection exists unless someone explicitly turns it on.
This is the part that surprises people who assume "overwrite" means what it sounds like. AWS's documentation is specific: "if you overwrite an object, Amazon S3 adds a new object version in the bucket. The previous version remains in the bucket and becomes a noncurrent version." Nothing gets destroyed, the bucket now simply holds two full copies under the same key, one marked current, one marked noncurrent, both individually retrievable by their version ID.
Delete behaves just as counterintuitively, and this is the detail worth internalizing above all others in this article. AWS states it directly: "if you delete an object, instead of removing the object permanently, Amazon S3 inserts a delete marker, which becomes the current object version." A normal GET request against that key now returns a 404, the object looks deleted from every ordinary vantage point, but nothing has actually been erased. Every prior version is still sitting in the bucket, retrievable by specifying its version ID directly.
Actual permanent deletion requires a different, more deliberate action: AWS's documentation notes that "you can permanently delete an object by specifying the version that you want to delete... Amazon S3 doesn't insert a delete marker" for that specific request. Casual deletion and permanent deletion are two different operations on purpose, not two names for the same thing.
Every version gets a unique, S3-assigned identifier, described in AWS's own documentation as "Unicode, UTF-8 encoded, URL-ready, opaque strings" that "cannot be edited." Two objects can share the exact same key and still be distinguished purely by this ID, photo.gif version 111111 and photo.gif version 121212 are AWS's own example of two genuinely different, independently retrievable objects living under one name.
For a use case where even a stolen or compromised credential shouldn't be able to quietly delete history, AWS offers a further layer: MFA Delete. Enabling it means "the bucket owner must include two forms of authentication in any request to delete a version or change the versioning state of the bucket," a real, meaningful barrier against exactly the kind of single-factor compromise that would otherwise let an attacker delete versions freely.
Versioning's protection isn't free, and AWS's own documentation is upfront about the mechanics: "normal Amazon S3 rates apply for every version of an object that is stored and transferred. Each version of an object is the entire object; it is not a diff from the previous version." Three versions of a file means paying for three complete copies, not one copy plus two small deltas. For a bucket with frequently-overwritten objects and no cleanup policy, that cost compounds indefinitely, every historical version just keeps accumulating storage charges forever.
The standard answer to that cost problem is a lifecycle rule specifically built for it: NoncurrentVersionExpiration. AWS's own API documentation describes it plainly: it "specifies when noncurrent object versions expire," and "upon expiration, Amazon S3 permanently deletes the noncurrent object versions," configurable by how many days a version has been noncurrent and how many noncurrent versions to retain before older ones get purged automatically. That turns versioning from an indefinitely-growing cost into a bounded one, recent history stays recoverable, ancient history ages out on a schedule instead of billing forever.
Object lock, S3's WORM immutability feature, isn't a separate mechanism bolted on top of storage generally, it's built directly on versioning. AWS states the dependency directly: enabling object lock automatically enables S3 Versioning, because object lock protects a specific version from deletion or modification, and that concept only exists once multiple versions of a key can coexist. Understanding versioning first is what makes object lock's actual behavior, and its Compliance-mode guarantee that not even a compromised root account can delete a locked version, make sense as a natural extension rather than a standalone rule to memorize.
AIOZ Storage's own documentation doesn't describe an object versioning feature anywhere, a real, citable gap already established elsewhere in this series and reconfirmed directly against /docs/concepts/definitions, which contains no mention of versioning, version IDs, delete markers, or noncurrent versions. That single missing feature is also the reason object lock isn't available either, since object lock has no foundation to build on without versioning underneath it. For workloads that depend on recovering an accidentally overwritten or deleted object, the honest workaround already covered elsewhere in this series still applies: a version identifier baked directly into the object key, or a tool like DVC layered on top, neither a true substitute for S3's version-ID mechanism, but a real way to avoid silently losing data in its absence.
What is S3 object versioning?
A feature that keeps every prior copy of an object when it's overwritten or deleted, each assigned a unique version ID, so an accidentally overwritten or deleted file can be recovered. It's disabled by default on every new bucket.
What happens when you delete an object in a versioned bucket?
By default, nothing is actually deleted. S3 inserts a delete marker that makes the object appear gone from normal requests, while every prior version remains fully intact and retrievable by its version ID.
How do you permanently delete a specific version?
By issuing a delete request that explicitly specifies that version's ID. That operation skips the delete marker entirely and actually removes that version, a deliberately different action from a normal delete.
Does keeping multiple versions cost more?
Yes. AWS's own documentation states each version is billed as a complete, separate object, not a diff, so three versions of a file means paying for three full copies indefinitely unless a lifecycle rule expires old ones.
How do you control the storage cost of old versions?
With a NoncurrentVersionExpiration lifecycle rule, which automatically and permanently deletes noncurrent versions after a set number of days, or beyond a set number of versions retained.
Why does object lock require versioning?
Because object lock protects a specific object version from being deleted or overwritten, a concept that only exists once multiple versions of the same key can coexist in a bucket. Enabling object lock automatically enables versioning for exactly this reason.
Does AIOZ Storage support object versioning?
No. AIOZ Storage's documentation doesn't describe a versioning feature, confirmed directly against its own concept-definitions page. That absence is also why AIOZ Storage doesn't support object lock, which depends on versioning entirely.

AIOZ Storage has no official MCP server yet. Here is a working MCP server for AIOZ Storage, built with the official Python SDK and boto3, tools included.

What is an MCP server: a standard letting AI agents like Claude use tools and data through one protocol. How MinIO and Azure apply it to object storage.

S3 access logs vs CloudTrail: AWS recommends CloudTrail, but each one catches real events the other misses. Speed, cost, and coverage, compared directly.

Eventual vs strong consistency: whether a read right after a write sees the new data immediately. S3 ran on the first model for 14 years, then changed it.

Bucket policy vs IAM policy: one attaches to the resource, one attaches to the identity. What each can do that the other can't, and how S3 evaluates both.

SSE-S3 vs SSE-KMS vs SSE-C: who manages the encryption key, and what that decision actually costs you. Includes the real 2026 default change to SSE-C.