Amazon S3 stores every object in a storage class that determines durability, availability, latency, and above all price. Choosing the right class is the single biggest lever on your S3 bill: the same terabyte costs about 23 USD per month in S3 Standard and about 1 USD in Glacier Deep Archive. This tutorial compares the eight current classes, explains the hidden costs (minimum durations, retrieval fees, per-object overhead), shows how to set the class from the CLI, the SDK and Terraform, and how to automate transitions with lifecycle rules.
Prerequisites: an AWS account, the AWS CLI v2 configured, and a test bucket (see S3 bucket creation). Prices below are US East (N. Virginia) list prices as of 2026, rounded, for orientation only; always check the S3 pricing page for your region (Canada Central is roughly 10 % higher).
The comparison table
| Storage class | API name | Storage $/GB-month | Retrieval $/GB | First-byte latency | Min. duration | Min. object size | AZs | Typical use |
|---|---|---|---|---|---|---|---|---|
| S3 Standard | STANDARD | 0.023 | none | ms | none | none | ≥ 3 | Active data, websites, analytics |
| S3 Intelligent-Tiering | INTELLIGENT_TIERING | 0.023 → 0.0125 → 0.004 (auto) | none | ms (opt-in archive tiers: minutes–hours) | none | 128 KB monitored | ≥ 3 | Unknown or changing access patterns |
| S3 Standard-IA | STANDARD_IA | 0.0125 | 0.01 | ms | 30 days | 128 KB | ≥ 3 | Backups, older files accessed monthly |
| S3 One Zone-IA | ONEZONE_IA | 0.01 | 0.01 | ms | 30 days | 128 KB | 1 | Re-creatable data, secondary copies |
| S3 Express One Zone | EXPRESS_ONEZONE | 0.11 | none (request-priced) | single-digit ms | none | none | 1 (directory bucket) | ML training, latency-critical workloads |
| S3 Glacier Instant Retrieval | GLACIER_IR | 0.004 | 0.03 | ms | 90 days | 128 KB | ≥ 3 | Archives read quarterly (medical images, media) |
| S3 Glacier Flexible Retrieval | GLACIER | 0.0036 | 0.01–0.03 (bulk free) | 1–5 min expedited, 3–5 h standard, 5–12 h bulk | 90 days | 40 KB overhead | ≥ 3 | Yearly archives, compliance |
| S3 Glacier Deep Archive | DEEP_ARCHIVE | 0.00099 | 0.02 | 12 h standard, 48 h bulk | 180 days | 40 KB overhead | ≥ 3 | 7–10 year retention, tape replacement |
All classes offer 99.999999999 % (11 nines) durability. They differ in availability SLA (99.99 % Standard, 99.9 % IA, 99.5 % One Zone), latency, and the fee structure.
Understanding the hidden costs
Minimum storage duration
Delete or overwrite an object in Standard-IA after 10 days and you are still billed for 30. Deep Archive charges 180 days. Never put short-lived data (temporary exports, CI artifacts) in IA or Glacier classes.
Minimum billable object size
IA classes bill every object as at least 128 KB. A million 4 KB thumbnails cost 128 GB in Standard-IA, more than the 4 GB they would cost in Standard. Glacier classes add 40 KB of metadata per object (8 KB in Standard + 32 KB in Glacier). Rule: small objects stay in Standard, or are bundled into archives before transition.
Retrieval and request fees
Reading 1 TB from Standard-IA costs about 10 USD in retrieval fees on top of requests. If you read the data more than once a month, Standard is cheaper. Glacier Flexible and Deep Archive also require a restore request that produces a temporary copy; bulk restores are the cheapest and slowest.
Transition requests
Lifecycle transitions are billed per 1 000 objects (about 0.01 USD to IA, 0.02 USD to Glacier Flexible, 0.05 USD to Deep Archive). Moving 50 million tiny log files to Deep Archive costs 2 500 USD in transitions alone. Aggregate first.
Worked cost example
10 TB of nightly database dumps, each read maybe once a year for audits:
| Class | Monthly storage | Yearly storage | One 10 TB audit restore |
|---|---|---|---|
| Standard | ≈ 235 USD | ≈ 2 820 USD | 0 |
| Standard-IA | ≈ 128 USD | ≈ 1 536 USD | ≈ 100 USD |
| Glacier Instant Retrieval | ≈ 41 USD | ≈ 492 USD | ≈ 300 USD |
| Glacier Deep Archive | ≈ 10 USD | ≈ 120 USD | ≈ 200 USD (bulk, 48 h) |
Deep Archive wins by a wide margin as long as a 12–48 hour wait is acceptable for audits; if auditors need files within minutes, Glacier Instant Retrieval is the compromise.
Setting the storage class
At upload time (CLI)
BUCKET=my-backups-123456789012
# Single object into Standard-IA
aws s3 cp dump-2026-09-10.sql.gz "s3://$BUCKET/db/" --storage-class STANDARD_IA
# Whole folder straight to Deep Archive
aws s3 sync ./archives/ "s3://$BUCKET/archives/" --storage-class DEEP_ARCHIVE
# Check the class of an object
aws s3api head-object --bucket "$BUCKET" --key db/dump-2026-09-10.sql.gz --query StorageClass
aws s3 ls "s3://$BUCKET/db/" --human-readable # add --summarize for totalsChanging the class of an existing object
S3 has no “move” call; you copy the object onto itself with a new class. For Glacier Flexible/Deep Archive objects you must restore first.
aws s3 cp "s3://$BUCKET/db/dump-2026-09-10.sql.gz" "s3://$BUCKET/db/dump-2026-09-10.sql.gz" \
--storage-class GLACIER_IR --metadata-directive COPY
# Restore an archived object for 7 days (bulk tier), then poll
aws s3api restore-object --bucket "$BUCKET" --key archives/2019.tar \
--restore-request '{"Days":7,"GlacierJobParameters":{"Tier":"Bulk"}}'
aws s3api head-object --bucket "$BUCKET" --key archives/2019.tar --query RestoreFrom Terraform
resource "aws_s3_object" "report" {
bucket = aws_s3_bucket.backups.id
key = "reports/2026-q3.pdf"
source = "reports/2026-q3.pdf"
storage_class = "STANDARD_IA"
etag = filemd5("reports/2026-q3.pdf")
}Automating with lifecycle rules
Lifecycle rules move objects between classes as they age and expire them at the end. The classic “backup waterfall” below keeps recent dumps hot, cools them after a month, archives after a year and deletes after seven.
{
"Rules": [
{
"ID": "backup-waterfall",
"Status": "Enabled",
"Filter": { "And": { "Prefix": "db/", "ObjectSizeGreaterThan": 131072 } },
"Transitions": [
{ "Days": 30, "StorageClass": "STANDARD_IA" },
{ "Days": 365, "StorageClass": "DEEP_ARCHIVE" }
],
"Expiration": { "Days": 2555 },
"AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
}
]
}aws s3api put-bucket-lifecycle-configuration --bucket "$BUCKET" --lifecycle-configuration file://lifecycle.json
aws s3api get-bucket-lifecycle-configuration --bucket "$BUCKET"The ObjectSizeGreaterThan filter (128 KB) avoids paying the IA minimum on small files, and the multipart rule cleans up abandoned uploads that otherwise cost money invisibly. Our S3 lifecycle management tutorial covers versioned buckets and noncurrent versions.
When Intelligent-Tiering is the right default
Intelligent-Tiering watches each object (≥ 128 KB) and moves it automatically: Frequent Access → Infrequent Access after 30 days without reads → Archive Instant Access after 90 days, back to Frequent on the next read, with no retrieval fees. The price is a small monitoring fee (0.0025 USD per 1 000 objects per month). For data lakes, user uploads and anything whose access pattern you cannot predict, it is the safest default. It is a poor fit for millions of tiny objects (monitoring fee dominates) and for data you know is cold from day one (go straight to Glacier).
Decision flow
- Need single-digit millisecond latency for hot, compute-adjacent data? → Express One Zone.
- Accessed often or unpredictably? → Standard (known hot) or Intelligent-Tiering (unknown).
- Accessed about monthly, objects > 128 KB, kept > 30 days? → Standard-IA; if easily re-creatable → One Zone-IA.
- Accessed quarterly or less, but must be instant when needed? → Glacier Instant Retrieval.
- Hours of delay acceptable, kept > 90 days? → Glacier Flexible Retrieval.
- Compliance archive, 12–48 h delay acceptable, kept > 180 days? → Glacier Deep Archive.
Key takeaways
- Durability is identical across classes; you are trading availability, latency and fees for storage price.
- Watch the three traps: minimum duration, 128 KB minimum size, and retrieval/transition fees.
- Intelligent-Tiering is the safe default for unpredictable access; Deep Archive is the tape replacement.
- Automate with lifecycle rules filtered by prefix and object size, and always clean incomplete multipart uploads.
Next tutorial
Next: S3 lifecycle management, then cross-region replication. Official docs: Using Amazon S3 storage classes.