All cheat sheets
Storagecheat sheet

S3 Batch Operations

Run one action across millions of S3 objects — storage-class changes, mass deletes, cross-account copies — for $0.25 per million, with automatic retries and an audit-grade completion report. No scripts to babysit.

Last reviewed: July 11, 2026

TL;DR: Batch Operations is AWS's forklift for S3: give it a manifest (usually from S3 Inventory) and an operation — change storage class, copy cross-account, restore from Glacier, retag, delete — and it executes across millions of objects in parallel, retries transient failures, and hands you a completion report that doubles as an audit trail. At $0.25 per million objects, it replaces the hand-rolled script that crashes at hour eight.

The numbers

  • Job cost: $0.25 per million objects, plus normal S3 request fees for the operation itself (a 10M-object class migration ≈ $2.50 + ~$50 in requests)
  • Worked example from the source workflow: a 50M-object log bucket at $8K/month → Inventory manifest, Athena-filtered to 45M objects older than 90 days, one Deep Archive transition job → under $500/month
  • Cross-account: 100 TB / ~30M objects moved in a two-day unattended job for a few dollars of Batch fees, versus a week of engineering and 3 AM pages for the DIY script

Do this

  1. Generate the manifest: enable S3 Inventory on the source bucket (first report within ~48 h), optionally filter it with Athena ("older than 90 days", "prefix = logs/", "untagged only").

  2. Set up the IAM role — the part everyone fumbles once: it needs read on the manifest, the operation permission on target objects, and write on the report destination.

  3. Dry-run with a 100–1,000 object manifest end-to-end. Most teams hit one IAM error on the test job and zero on the real one — that's the right ratio.

  4. Run the real job (console or aws s3control create-job) and let the completion report tell you exactly what succeeded, with timestamps and error codes per object.

  5. Add the lifecycle rule afterward so the backlog can't re-accumulate — Batch Operations clears the past; lifecycle policies govern the future.

Gotchas

  • No undo. Ten million deletes have no Ctrl+Z; the completion report is your only record. This is why the small-manifest dry run isn't optional.
  • Glacier minimum-duration charges apply to migrations. Move data to Glacier Flexible (90-day min) or Deep Archive (180-day min) and change your mind next month — you pay the minimum anyway.
  • Restores still take Glacier time. Batch orchestrates mass restores; it doesn't accelerate them.
  • Lambda-per-object jobs are a Lambda bill. A million objects = a million invocations; right-size memory before you fan out.
  • The completion report lands in S3, not the console — you download and parse it.

Skip this if

  • The object count is small — dozens or hundreds of objects are a CLI loop, not a job.
  • The work is incremental ("process each new upload") — that's S3 Event Notifications + Lambda.
  • The logic is deeply conditional per object — Batch is for uniform actions across a known set; branching logic wants a custom script or the Lambda-invoke operation with care.

Run this audit with your AI assistant

Paste this into Claude, ChatGPT, or any agent that can run the AWS CLI with read-only credentials. It audits your account for exactly the waste this sheet describes — and changes nothing.

You are scoping (report-only) S3 Batch Operations jobs that would clean
up an AWS account's storage backlog. Use the AWS CLI with READ-ONLY
credentials. Do not create, modify, or delete anything — report findings
and recommended (unapplied) job specs only.

1. Backlogs worth a batch job:
   - Cold objects in STANDARD that lifecycle rules only cover going
     forward (rules exist but large pre-rule backlog remains): compare
     bucket age vs rule creation, CloudWatch BucketSizeBytes by class.
   - Version bloat / expired data flagged by prior audits.
   - Buckets needing mass re-tagging for cost allocation (objects
     missing the org's cost tags).
2. Manifest sources: does S3 Inventory exist on the relevant buckets?
   aws s3api list-bucket-inventory-configurations --bucket <b>
   If not, note it must be enabled ~48h before a manifest is available.
3. Existing/past jobs: aws s3control list-jobs --account-id <acct> —
   anything failed or suspended worth mentioning?
4. For each proposed job estimate cost: $0.25/million objects + request
   fees (e.g., ~$0.005/1,000 PUTs for class transitions; Glacier
   transition requests cost more) and the monthly savings it unlocks.
   Warn about Glacier minimum-duration charges if the data might move
   back.

Report: proposed jobs table (bucket | objects | operation | one-time
cost | $/mo saved), the IAM role permissions each job needs (manifest
read, operation on targets, report write), and a reminder to dry-run
with a 100-object manifest first. Do NOT create any job.
Works with any assistant that can run shell commands.

Want the guided version?

The S3 Batch Operations walkthrough covers this topic interactively — it asks about your setup, branches to what’s relevant, and quizzes you on the tricky parts. Free and anonymous.

Start the walkthrough