What is S3 versioning?
S3 versioning is a bucket setting in the S3 API that keeps every version of every object under the same key, each with its own version ID. An overwrite adds a new version instead of replacing the old one, and a plain delete hides the object instead of erasing it. Earlier versions stay readable until you remove them.
Think of a document editor with version history. Saving over a file does not destroy yesterday’s draft, and you can open any older draft and make it the current one again.
Versioning is off by default. Once you enable it on a bucket, the bucket can never go back to unversioned. You can only suspend it.
How does versioning work?
A versioned bucket holds one current version per key and zero or more noncurrent versions. A normal GET returns the current version. A GET with a version ID returns that exact version, even if it is no longer current.
Every version is a full copy of the object, not a diff. Three versions of a 1 GB file take 3 GB of storage.
Delete markers
A DELETE without a version ID does not remove any data. It adds a delete marker, a placeholder with a key and a version ID but no content, and makes it the current version. A normal GET now returns 404, and a normal listing no longer shows the object.
The older versions are all still there. To undo the delete, remove the delete marker by its version ID, and the previous version becomes current again.
Permanent deletes
A DELETE that names a version ID removes that version for good and creates no delete marker. This is the only way to destroy data in a versioned bucket. Anyone who holds that permission can wipe the history, which is why versioning pairs with Object Lock.
Suspended versioning
In a suspended bucket, new uploads get the version ID “null” and overwrite any existing null version. Versions created while versioning was enabled stay in place. A plain delete removes the null version, if there is one, and puts a delete marker in its place.
How do you restore an earlier version?
There are two ways, and both use the version ID of the version you want back:
- Copy the old version onto the same key. It becomes a new current version, and all existing versions are kept.
- Permanently delete the newer versions or the delete marker above it. The old version becomes current again.
Copying is the safer default, because it keeps the full history in case you pick the wrong version.
What does versioning not protect against?
Versioning protects against overwrites, accidental deletes and buggy scripts. It does not stop someone with the right permissions from deleting specific versions. Object Lock closes that gap: in compliance mode, nobody can delete a locked version until its retention period ends.
Versioning also keeps everything in the same bucket and the same zone. Keep a copy elsewhere of data you cannot afford to lose.
Without cleanup, history only grows. Lifecycle rules can expire versions a set number of days after they become noncurrent, keep only the newest few, and remove delete markers that no longer have any versions behind them.
How enum handles S3 versioning
enum Object Storage supports versioning, Object Lock and lifecycle rules through the S3 API, so existing tools such as rclone and s3cmd work unchanged. Object Lock is enabled when you create the bucket. Storage is billed per GB a month, and noncurrent versions are stored data, so add a lifecycle rule that expires old versions.
FAQ
Does versioning cost extra? You pay for what it stores, and every version is a full object that takes storage. A file overwritten daily for a month can hold thirty times its size unless a lifecycle rule expires old versions.
Can I turn versioning off again? You can suspend it, but a bucket that has had versioning enabled never returns to unversioned. Existing versions stay after suspending, and new uploads overwrite a single null version instead of adding new ones.
Why does my bucket look empty but still use storage? Objects whose current version is a delete marker do not show up in normal listings. Their noncurrent versions still take space. List object versions to see them, then expire or delete what you no longer need.