S3 is two products in a trench coat. There's the storage product — $0.023/GB/month for Standard, less for cooler tiers — and there's the request product. The first one is what people estimate. The second one is what blows the budget.
A bucket with 1 TB of objects at Standard costs $23/month for storage. The same bucket serving 50 million GET requests a month adds another $20. Add 10 million PUTs and that's another $50. Add lifecycle transitions, replication, Inventory, and Intelligent-Tiering monitoring fees, and the storage-only estimate is somewhere between half and a third of the actual bill.
The four-dimensional cost surface
- Storage — per GB-month. Varies 5× across classes (Standard, IA, One Zone-IA, Glacier Instant, Glacier Flexible, Deep Archive).
- Requests — per 1,000. PUTs are ~10× the cost of GETs. Cooler classes have higher request prices to discourage frequent access.
- Lifecycle transitions — $0.01 per 1,000 transitions. Sounds tiny. With 100M objects transitioning monthly, that's $1,000.
- Retrieval fees — IA and Glacier classes charge per-GB on read. A "cold" file you accidentally read often costs more than just leaving it in Standard.
The small-files tax
Many "S3 problems" are actually small-files problems. S3 has a minimum billable object size of 128 KB for IA and Glacier Instant. If your bucket is full of 10 KB objects, you're paying for 128 KB of "storage" on every single one — a 12× overhead.
| Object profile | 1 TB raw | Storage class | Actual monthly cost |
|---|---|---|---|
| 1M objects @ 1 MB | 1 TB | Standard | ~$23 |
| 100M objects @ 10 KB | 1 TB | Standard | ~$23 |
| 100M objects @ 10 KB | 1 TB raw | IA (billed at 128 KB min) | ~$160 storage + $40 request |
| 10M objects @ 100 KB w/ Intelligent-Tiering | 1 TB | Intelligent-Tiering | ~$23 + $2.50 monitoring |
When Intelligent-Tiering is worth it
IT wins
Object >128 KB, access pattern unknown or variable. Monitoring fee ($0.0025/1k objects/month) is negligible at scale. Auto-archives cold data without you tracking it.
IT loses
Object <128 KB (minimum billable), known-cold data (just transition manually), buckets with millions of tiny objects (monitoring fees compound).
The "set it and forget it" trap
Intelligent-Tiering on a bucket of small objects can cost more than Standard. Run the simulation before enabling.
Where request fees catch you
- S3 Select / HeadObject in hot paths. Each is a request. Some application architectures call HeadObject before every GetObject "for safety" — doubling the request bill.
- S3 as a database. Storing per-user JSON blobs and reading them on every page view. Cheap until you have a million users.
- Inventory + Analytics + Storage Lens — each has a cost. Combined on every bucket, they can add a meaningful line.
Drop an S3 bucket on the pinpole canvas. Configure average object size, total objects, monthly PUT/GET/LIST rates, and lifecycle policy. Toggle storage classes and Intelligent-Tiering. The simulator returns a four-line cost breakdown — storage, requests, transitions, monitoring. The one that's largest tells you where to optimise.
What to actually change
- Aggregate small files. Roll 1000s of small objects into Parquet/Avro batches if your reader can handle it. The request savings dwarf the storage cost difference.
- Set realistic lifecycle. Standard → IA at 30 days is fine for many workloads. Aggressive Glacier transitions for hot data is a footgun (retrieval fees).
- Audit Inventory + Analytics. Turn off the buckets you don't actively use them on.
- Use S3 Express One Zone for hot transactional data. Higher storage cost, dramatically lower request cost. Wins for tiny-object hot workloads.
S3 is the AWS service most often misunderstood at design time.
Simulate request patterns, storage classes, and lifecycle policies before you commit. Pinpole's canvas surfaces the four-dimensional cost surface live.
Start 14-day free trial →