awss3storagecost-optimization

S3 versioning storage cost: why old versions inflate your bill

S3 versioning protects against overwrites and deletes, but every version is a full object billed at the full storage rate. Without lifecycle rules to expire noncurrent versions, a versioned bucket can store several times the data you think it does. Here is how to keep it in check.

The C3X Team··6 min read

Quick answer

S3 versioning stores every version of an object as a full, separately billed object at the normal storage rate (for example $0.023 per GB-month in S3 Standard). It has no separate feature fee, but overwriting a 10 GB object daily keeps every old copy, so a month of edits stores 300 GB, not 10. Deletes add delete markers and keep the prior version too. The fix is a lifecycle rule that transitions or expires noncurrent versions, for example moving them to Glacier after 30 days and deleting them after 90, which can cut a versioned bucket's storage cost by 60 to 90 percent.

S3 versioning is one of the best safety features S3 offers: it keeps every version of an object so an accidental overwrite or delete is recoverable. It is also one of the quietest cost multipliers, because AWS bills every version as a full object at the full storage rate. A bucket you think holds 5 TB can easily be storing 15 TB of current plus noncurrent versions, and the bill reflects the 15.

How versioning is billed

Versioning has no per-feature charge. Each version, current or noncurrent, occupies storage at the same rate as any other object: $0.023 per GB-month in S3 Standard, or the rate of whatever class the version sits in. There is no deduplication between versions, even if only a few bytes changed, because S3 stores whole objects, not deltas. Overwrite a 100 MB file and you now store 200 MB. Overwrite it ten times and you store 1 GB, of which 900 MB is history you are paying to keep.

ScenarioLogical sizeActual storedMonthly (Standard)
10 GB object, no versioning10 GB10 GB$0.23
10 GB overwritten daily, 30 days10 GB300 GB$6.90
Same, noncurrent expired at 7 days10 GB~80 GB$1.84

Delete markers and the hidden pile-up

Deletes behave surprisingly under versioning. Deleting an object does not remove it; it adds a zero-byte delete marker and keeps the previous version, which still bills. So a bucket where objects are regularly written and deleted can accumulate noncurrent versions indefinitely while appearing empty in the console listing. This is the classic cause of a versioned log or temp bucket that quietly grows to terabytes. The current-version view looks small; the noncurrent versions underneath are the bill.

Lifecycle rules are the fix

The remedy is a lifecycle configuration targeting noncurrent versions specifically. A typical rule transitions noncurrent versions to a cheaper class such as Standard-IA or Glacier after 30 days, then expires them after 90, and also cleans up expired delete markers. For churny data, expiring noncurrent versions after 7 to 30 days is enough to keep recovery useful while cutting storage 60 to 90 percent. See lifecycle policies for the mechanics and the storage class comparison for where to send old versions.

Right-sizing the retention

The question is not whether to keep versions but how long. Compliance data may need years of history; a build artifact bucket may need days. Match the noncurrent expiration to the actual recovery requirement rather than leaving the default of forever. Keeping three days of noncurrent versions on a fast-churning bucket gives real protection against fat-finger mistakes at a fraction of the cost of keeping every version indefinitely. For rarely-restored history, Glacier or Deep Archive stores old versions for as little as $0.00099 per GB.

Know the real size before it grows

Versioning cost creeps because the console shows current versions while the bill counts all of them. Enable it for the safety, but pair it with a noncurrent-version lifecycle rule from day one, and check the actual stored bytes in Storage Lens or the bucket metrics rather than trusting the object listing. Price the bucket, including its versioning and lifecycle configuration, against the resource catalog so the true storage footprint is understood before the history piles up.

FAQ

Does S3 versioning cost extra?

There is no separate feature fee, but every version is stored as a full object billed at the normal storage rate, for example $0.023 per GB-month in S3 Standard. S3 does not deduplicate between versions, so overwriting a 10 GB object daily stores 300 GB after a month. The storage of all those noncurrent versions is the real cost of versioning.

Why is my versioned S3 bucket so large?

Because noncurrent versions and delete markers accumulate. Deleting an object under versioning adds a delete marker and keeps the previous version, which still bills, so a bucket can grow to terabytes while looking empty in the listing. Every overwrite also keeps the old version. Without a lifecycle rule to expire noncurrent versions, they pile up indefinitely.

How do I reduce S3 versioning storage cost?

Add a lifecycle rule targeting noncurrent versions: transition them to a cheaper class like Standard-IA or Glacier after 30 days, expire them after a retention period matched to your recovery needs (often 7 to 90 days), and clean up expired delete markers. This typically cuts a versioned bucket's storage cost by 60 to 90 percent while keeping useful recovery history.

What happens to old versions when I delete an object in S3?

Under versioning, a delete does not remove data. It adds a zero-byte delete marker and retains the previous version, which continues to bill at the full storage rate. The object disappears from the default listing but the noncurrent version underneath still costs money until a lifecycle rule expires it.

How does C3X help with S3 versioning cost?

C3X prices S3 buckets from Terraform including whether versioning is enabled and what lifecycle rules govern noncurrent versions, so the risk of unbounded version growth is visible in the pull request. That prompts teams to add a noncurrent-version expiration rule at design time rather than discovering a multi-terabyte version pile-up on a later invoice.

What to do next

Keep versioning safe without letting old versions inflate the bill. C3X prices S3 buckets and lifecycle rules from Terraform against a live resource catalog. Start with the quickstart.

Try C3X on your own Terraform

Free and open source. No API key required. One command to install, one command to estimate.