AWS S3 incomplete multipart upload cost hides in MPU / abort-related usage types while everyone stares at Intelligent-Tiering. A client uploads a 40 GB object, the network dies at 90%, and the parts sit. S3 keeps charging until you abort. Teams with CI artifacts and data-lake landings accumulate this for years.
This is a 2-week audit item: find buckets without abort lifecycle rules, apply them, then watch the bill line. It does not replace S3 Intelligent-Tiering — it is a different lever.
Why Intelligent-Tiering Does Not Fix It
Incomplete multipart parts are not the same as stored objects in a class. Lifecycle transitions on objects do not abort uploads. AWS documents aborting incomplete uploads via lifecycle rules. If the rule is missing, Cost Explorer will keep showing a quiet tax.
{
"Rules": [
{
"ID": "abort-stale-mpu",
"Status": "Enabled",
"Filter": { "Prefix": "" },
"AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
}
]
}
Seven days is a starting point. Video pipelines that legitimately run longer need a longer abort or a Completer job — not "no rule."
Inventory Before You Enable Abort
- S3 Storage Lens /
ListMultipartUploadson high-spend buckets - Which prefixes are CI vs human uploads vs partner landings
- Whether versioning + replication copies the problem (usually not for MPU, but check replication configs anyway)
- Terraform coverage: if lifecycle lives only in the console, the next bucket ships naked
We attach this to multi-account tagging so you can see which team owns the MPU spend. Untagged log buckets are the usual offender.
Do Not Abort 1-Day Uploads Blindly
Scientific and media workloads sometimes need >7 days. We set abort by prefix, not one global number. A 1-day abort on a 200 GB research upload is an outage disguised as FinOps.
After rules land, we confirm AbortIncompleteMultipartUpload in Config or a custom Config rule — detective control, same spirit as other SOC 2-ready AWS hygiene.
A 2-week AWS cost audit includes MPU as a scored line → rutagon.com/contact · 907-841-8407 · contact@rutagon.com.
How MPU Spend Hides in Cost Explorer
Filter usage types containing TimedStorage-MPU / incomplete multipart (names vary by region and report). If the line is zero, either you already abort or you have not waited a billing cycle. Storage Lens "incomplete MPU bytes" is the operational view; Cost Explorer is the CFO view. We screenshot both in the scorecard because they disagree during the first month of a new rule.
Terraform bucket modules get a default abort_incomplete_multipart_upload { days_after_initiation = 7 } with an override map for prefixes that legitimately run long (research drops, partner EDI). A module without the default is how the next data lake lands naked.
Replication, Inventory, and Versioning
Same-region replication does not copy in-progress MPU parts the way people fear, but inventory jobs and S3 Inventory reports can still list uploads. We do not disable inventory to "save MPU" — that confuses two products. We abort the uploads.
If a partner uploads with a client that retries forever without completing, aborting at 7 days is correct and they must fix the client. If you are the partner uploading into a customer's bucket, put the abort rule on their bucket in the contract so you are not the surprise bill.
CloudFront or Transfer Family landings into S3 can leave parts too. Include those prefixes in the inventory, not only s3://data-lake/raw/.
AWS S3 incomplete multipart upload cost after the first abort rule
AWS S3 incomplete multipart upload cost does not drop the hour you attach a lifecycle rule. Billing lags. Storage Lens “incomplete MPU bytes” is the operational graph; Cost Explorer is the finance graph. We screenshot both after 7 and 30 days because they disagree during the first cycle. If Storage Lens is flat and Cost Explorer still shows MPU, you aborted the wrong prefixes.
AWS documents aborting incomplete uploads in S3 lifecycle examples. Terraform modules should default days_after_initiation = 7 with an override map for research drops and partner EDI that legitimately run longer. A data-lake bucket created outside the module is how the tax returns.
Transfer Family, CloudFront POSTs, and CI artifact uploads are first-class prefixes in the inventory. Teams only look at s3://raw/. The expensive abandoned uploads are often s3://gitlab-runner-cache/ from a job that died mid-PUT.
Do not disable S3 Inventory to “save MPU.” Inventory is a different product. Abort the uploads. If a partner’s client retries forever, aborting at 7 days is correct; the contract should say whose bucket carries the abort rule so the bill is not a surprise.
Who pays for abandoned MPU in a shared data-lake account
Shared buckets without prefix ABAC turn abort rules into politics. Team A’s 14-day scientific drop and Team B’s crashed CI cache live in the same bucket. One global 1-day abort “to save money” breaks science; one global never-abort burns finance. Prefix rules plus an owner tag on the prefix is the adult version.
We include MPU bytes on the weekly FinOps scorecard next to NAT and idle load balancers so it cannot hide as “miscellaneous storage.” If the number does not fall a billing cycle after the rule, the rule is on the wrong bucket or the wrong account.
Frequently Asked Questions
Will aborting uploads delete finished objects?
No. Abort targets incomplete multipart uploads, not committed objects. Test on a prefix first if you are nervous.
Is this the same as deleting old object versions?
No. Versioning costs are a different lifecycle (noncurrent version expiration). Do not mix the two rules without reading both.
How do we find spend today?
Cost Explorer usage types containing MPU / multipart, plus Storage Lens "incomplete multipart upload" metrics where available. Then list-multipart-uploads for proof.
Can we rely on the S3 console recommendation banner?
Banners miss buckets created by Terraform the next day. Encode the abort rule in the bucket module.
Does Transfer Acceleration change MPU billing?
It can change transfer pricing. It does not expire abandoned parts. You still need abort rules.