Versioning
Versioning is opt-in and configured at bucket creation time. Once enabled on a bucket, it cannot be suspended or disabled. Every time you upload an object with the same key on a versioned bucket, Fil One creates a new version rather than overwriting the previous one.
This means your data is always recoverable — you can retrieve any previous state of an object using its version ID.
To enable versioning, turn on the Versioning toggle when creating a bucket in the dashboard. Versioning is required for Object Lock.
How versions work
When you upload reports/q1.pdf for the first time, Fil One creates version v1. If you upload a new reports/q1.pdf tomorrow, Fil One creates version v2 and v1 remains intact. If you delete the object, Fil One places a delete marker at the current version — the object appears deleted, but all previous versions are still retrievable.
This behavior applies to all objects in versioned buckets.
Billing implications
Every version is a full copy of the object and is billed as stored storage. If you upload and then overwrite 100 files, you have 200 billable object versions consuming storage. Consider cleaning up old versions if storage cost is a concern. See Pricing.
Listing versions
- AWS CLI
- Python (boto3)
# List all versions in a bucket
aws s3api list-object-versions \
--bucket my-bucket \
--profile filone
# List versions for a specific object
aws s3api list-object-versions \
--bucket my-bucket \
--prefix reports/q1.pdf \
--profile filone
paginator = s3.get_paginator("list_object_versions")
for page in paginator.paginate(Bucket="my-bucket", Prefix="reports/q1.pdf"):
for version in page.get("Versions", []):
print(version["VersionId"], version["LastModified"], version["Size"])
for marker in page.get("DeleteMarkers", []):
print("DELETE MARKER", marker["VersionId"], marker["LastModified"])
Retrieving a specific version
- AWS CLI
- Python (boto3)
aws s3api get-object \
--bucket my-bucket \
--key reports/q1.pdf \
--version-id YOUR_VERSION_ID \
q1-old.pdf \
--profile filone
s3.download_file(
"my-bucket",
"reports/q1.pdf",
"q1-old.pdf",
ExtraArgs={"VersionId": "YOUR_VERSION_ID"},
)
Going back to a previous version
The Fil One dashboard has no restore, roll-back, or "make current" button — you can list, download, and delete prior versions there, but not promote one to current.
Promoting a version to current with CopyObject is confirmed working in us-east-1. This has not yet been confirmed in eu-west-1 — use the download-and-reupload method there instead.
In us-east-1: copy the version onto the current key
Use CopyObject with x-amz-copy-source-version-id to promote an older version to current in place:
- AWS CLI
- Python (boto3)
aws s3api copy-object \
--bucket my-bucket \
--key reports/q1.pdf \
--copy-source "my-bucket/reports/q1.pdf?versionId=OLD_VERSION_ID" \
--profile filone
s3.copy_object(
Bucket="my-bucket",
Key="reports/q1.pdf",
CopySource={
"Bucket": "my-bucket",
"Key": "reports/q1.pdf",
"VersionId": "OLD_VERSION_ID",
},
)
This creates a new current version with the old content; the version you copied from stays intact.
In eu-west-1, or as a universal fallback: download and re-upload
To go back to an earlier version without CopyObject, download it and upload it again. The re-upload becomes a new current version, and the version you copied from stays intact.
- AWS CLI
- Python (boto3)
aws s3api get-object \
--bucket my-bucket \
--key reports/q1.pdf \
--version-id OLD_VERSION_ID \
q1-restored.pdf \
--profile filone
aws s3api put-object \
--bucket my-bucket \
--key reports/q1.pdf \
--body q1-restored.pdf \
--profile filone
old = s3.get_object(
Bucket="my-bucket",
Key="reports/q1.pdf",
VersionId="OLD_VERSION_ID",
)
s3.put_object(
Bucket="my-bucket",
Key="reports/q1.pdf",
Body=old["Body"].read(),
)
If the current version is a delete marker, you can instead make the object visible again by deleting that delete marker by its version ID — see below.
Delete markers
When you delete an object without specifying a version ID, Fil One places a delete marker at the top of the version stack. The object appears deleted in standard listings and GetObject returns NoSuchKey. The previous versions remain intact and can be retrieved by version ID.
To permanently delete a specific version (including a delete marker), specify the version ID in the delete request:
- AWS CLI
- Python (boto3)
# Delete a specific version permanently
aws s3api delete-object \
--bucket my-bucket \
--key reports/q1.pdf \
--version-id YOUR_VERSION_ID \
--profile filone
# Remove a delete marker (restores the object to visible)
aws s3api delete-object \
--bucket my-bucket \
--key reports/q1.pdf \
--version-id DELETE_MARKER_VERSION_ID \
--profile filone
# Delete a specific version permanently
s3.delete_object(
Bucket="my-bucket",
Key="reports/q1.pdf",
VersionId="YOUR_VERSION_ID",
)
Permanently deleting a version cannot be undone. If the version has an active Object Lock Compliance retention, the delete request will be rejected.
Versioning and Object Lock
Object Lock is configured on the bucket, when the bucket is created. You enable it there and set a default retention mode and duration, and Object Lock requires versioning to be enabled on the same bucket. Neither can be turned on later.
Retention is then tracked per version. The bucket's default retention is applied to each new object version as it is uploaded, and each version carries its own retention independently — locking one version does not affect the versions above or below it, and older versions keep their own settings.
What that means in practice:
- You cannot delete a version that is under active Compliance retention, regardless of whether a delete marker exists above it.
- A delete marker is not itself protected by retention, so an object can still appear deleted while its underlying versions remain locked and intact.
- Because retention comes from the bucket default, a bucket with a long default retention will accumulate locked versions on every overwrite. Each one is billed as stored storage and cannot be removed until its retention expires.
See Object Lock for modes, durations, and examples.