Versioning is a practice in software development and data management that involves assigning unique identifiers or labels to different versions of a piece of software, a file, or a dataset. This enables tracking changes over time, maintaining a history of modifications, and facilitating collaboration among multiple contributors.

Press + to interact
Versioning of a file
Versioning of a file

In Amazon S3, versioning enables the storage of multiple versions of an object in a bucket. This helps protect against accidental deletions or overwrites, and it can restore previous versions.

Enabling versioning on buckets

By default, versioning is disabled in S3 buckets. We can enable the versioning while creating a bucket. Also, we can enable or disable the versioning of an existing bucket. Therefore, a bucket can be in one of the three states:

  • Unversioned: We disable the versioning of the bucket while creating it.

  • Versioning-enabled: We enable the versioning of a bucket while creating it or modify it later on.

  • Versioning-suspended: We disable the versioning of a versioning-enabled bucket.

Press + to interact
Three states of a bucket
Three states of a bucket

Since space is consumed by all the versions of an object in the bucket, S3 charges for every version of the object in the bucket. So when we suspend the versioning in a bucket, S3 charges us for the previously stored versions of the objects. The way to minimize the costs in such a scenario is to create another S3 bucket and upload all the current versions or delete the previous versions manually.

Versioning configuration

The version configuration is stored in a versioning subresource attached to the S3 bucket. For an unversioned bucket, an empty versioning subresource stores an empty configuration.

Another important setting that is enabled in the bucket versioning configuration is MFA Delete. When enabled, MFA delete requires MFA to change the state of the bucket versioning. Also, it requires MFA when deleting versions of objects. It works by requiring MFA serial numbers and the code generated by it for any API calls to change the bucket state or delete an object version.

When we enable versioning on a bucket, it changes the status in the version configuartion and automatically starts generating version IDs for the objects. S3 buckets itself assigns immutable version IDs. For example, if we add an image named my-image.png in a version-enabled S3 bucket, the bucket will assign a version ID such as shown in the figure below:

Press + to interact
Unversioned bucket
Unversioned bucket
1 of 2

If we enable versioning of a nonempty bucket, the S3 bucket assigns an ID of null to all the existing objects. It then assigns numeric version IDs to any new objects. Similarly, if we decide to suspend the versioning of a bucket, it does not change the version ID of existing objects and only handles the newly added objects differently.

Add an object to a version-enabled bucket

When we PUT an object in a bucket, it checks if an object with a similar key exists. If not, it assigns a version ID and stores it in the bucket. If it already exists, the S3 bucket assigns it a version ID and stores it in the bucket. For example, if we want to store an image named my-image.png in the S3 bucket, and an image with a similar name already exists, it will store the new image with a different version ID. The latest image becomes the current version. This way, the previous version of the image, or the noncurrent version, is easily recovered.

Press + to interact
Version 1
Version 1
1 of 2

Note: An S3 bucket only creates a new version when we PUT an object.

Get an object from a version-enabled bucket

When we send a GET request to an S3 bucket API for an object with a specific key value; it returns the latest version. For example, when we fetch the my-image.png from the S3 bucket, it will return the current version.

Press + to interact
Get object from the version-enabled bucket
Get object from the version-enabled bucket

However, we can fetch the noncurrent version of an object from an S3 bucket by specifying the version ID of the object in the GET request.

Delete an object from a version-enabled bucket

When we DELETE the current version of an object from a version-enabled bucket, the bucket inserts a delete marker for the object. The delete marker is just the newer version of the object, which becomes the current version. This means when we send GET request to the bucket for the object, it will return a 404 Not Found error.

The delete marker does not take up much space, and its size is only equal to the size of the key name.

Press + to interact
Delete an object
Delete an object
1 of 2

However, we can permanently delete an object by specifying the version ID. When we delete a version object by specifying the Version ID, S3 deletes the object version and makes the most recent version the current version. The S3 bucket does not store a delete marker in this case.

If we accidentally delete an object, we can restore it by either sending a GetObject request for a specific version ID or removing the delete marker, which effectively restores the previous version of the object.

Get hands-on with 1300+ tech skills courses.