S3 is object storage: unlimited objects in buckets, designed for 11 nines of durability. Overview is in 4. AWS Storage and Databases; securing it is also covered in 4. Cloud Security.
Parts at a glance
| Part | Role |
|---|---|
| Bucket | Container with a globally unique name, in one Region |
| Object | Data + key (name) + metadata; up to 5 TB |
| Key / prefix | Full name (reports/2026/jan.csv); "folders" are just prefixes |
| Storage class | Cost vs retrieval speed trade-off |
| Versioning | Keeps every version of an object |
| Lifecycle rule | Moves or expires objects automatically |
| Bucket policy | Resource policy controlling access |
| Access point | Named entry with its own policy for a shared bucket |
| Replication | Copies objects to another bucket or Region |
Strong read-after-write consistency applies to all operations. Single PUT up to 5 GB; use multipart upload above about 100 MB and required above 5 GB.
Storage Classes
| Class | Use | Retrieval |
|---|---|---|
| Standard | Frequently accessed data | Instant |
| Intelligent-Tiering | Unknown or changing access; moves objects between tiers automatically | Instant tiers (plus optional archive tiers) |
| Standard-IA | Infrequent access, multi-AZ | Instant, retrieval fee |
| One Zone-IA | Re-creatable infrequent data, one AZ | Instant, retrieval fee |
| Glacier Instant Retrieval | Archive needing millisecond access | Instant |
| Glacier Flexible Retrieval | Archive; minutes to hours | Expedited / Standard / Bulk |
| Glacier Deep Archive | Cheapest, long-term retention | Hours (about 12 h or more) |
| Express One Zone | Very low latency for hot data | Single-digit milliseconds |
IA and Glacier classes have minimum storage durations and minimum object size charges; deleting early still bills the minimum.
Lifecycle Rules
{
"Rules": [{
"ID": "archive-and-expire-logs",
"Status": "Enabled",
"Filter": { "Prefix": "logs/" },
"Transitions": [
{ "Days": 30, "StorageClass": "STANDARD_IA" },
{ "Days": 90, "StorageClass": "GLACIER" }
],
"Expiration": { "Days": 365 },
"NoncurrentVersionExpiration": { "NoncurrentDays": 30 },
"AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
}]
}
$ aws s3api put-bucket-lifecycle-configuration --bucket my-unique-bucket-12345 --lifecycle-configuration file://lifecycle.json
Always include abort incomplete multipart uploads and expire noncurrent versions; both silently accumulate cost.
Versioning, MFA Delete and Object Lock
- Versioning: every overwrite or delete keeps history; a delete adds a delete marker. Recover by removing the marker or fetching an older version. Once enabled it can only be suspended
- MFA Delete: require MFA to permanently delete versions
- Object Lock (needs versioning): WORM protection
- Governance mode: privileged users can override
- Compliance mode: nobody, not even root, can delete until retention ends
- Legal hold: indefinite hold until removed
- Use for ransomware resilience and regulated retention
Encryption
| Option | Keys |
|---|---|
| SSE-S3 | S3-managed keys. Applied by default to all new objects |
| SSE-KMS | KMS key you control; audit with CloudTrail; request costs apply (use S3 Bucket Keys to cut them) |
| DSSE-KMS | Two layers of KMS encryption |
| SSE-C | You supply the key on every request |
| Client-side | Encrypt before upload |
In transit: enforce TLS with a bucket policy:
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::my-unique-bucket-12345", "arn:aws:s3:::my-unique-bucket-12345/*"],
"Condition": { "Bool": { "aws:SecureTransport": "false" } }
}
Access Control
Evaluation: an explicit deny wins; otherwise access needs an allow from IAM or the bucket policy (same account) or both (cross-account).
| Tool | Use |
|---|---|
| IAM policy | What a user or role may do |
| Bucket policy | Who may access this bucket (accounts, CloudFront, VPC endpoint, IP) |
| Block Public Access | Account- and bucket-level switches that override public policies and ACLs. Keep on |
| Object Ownership: Bucket owner enforced | Disables ACLs; the default for new buckets |
| Access points | Per-application policies and VPC-only access for shared data |
| Presigned URLs | Time-limited access to one object without credentials |
| VPC gateway endpoint | Private path from a VPC with an endpoint policy; no internet or NAT cost |
| Access Analyzer for S3 | Finds buckets shared publicly or cross-account |
$ aws s3 presign s3://my-unique-bucket-12345/report.pdf --expires-in 900
$ aws s3api put-public-access-block --bucket my-unique-bucket-12345 \
--public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
Hosting Static Sites
| Approach | Notes |
|---|---|
| S3 website endpoint | HTTP only, public bucket, index / error documents, redirects |
| S3 + CloudFront + OAC (recommended) | Private bucket, HTTPS, custom domain, caching, security headers: AWS CloudFront Deep Dive |
Events and Integrations
- Event notifications to Lambda, SQS, SNS or EventBridge on object create, remove, restore, replication
- Typical pipeline: upload, event, Lambda processes (thumbnails, parse CSV), result written back to another bucket (use a different bucket or prefix to avoid trigger loops)
- Athena queries data in place; S3 Select / Glacier restore for partial reads; Batch Operations for bulk changes (copy, tag, restore, invoke Lambda)
- Inventory reports list objects and metadata for audits
Replication
| Type | Use |
|---|---|
| CRR (cross-Region) | Disaster recovery, lower latency, compliance |
| SRR (same-Region) | Aggregate logs, separate accounts, live copy |
Requires versioning on both buckets and an IAM role. Replicates new objects by default; use Batch Replication for existing ones. Delete markers replication is optional. Replication Time Control gives a time-bound SLA.
Performance
- Scales to thousands of requests per second per prefix; spread hot keys across prefixes
- Multipart upload for large files, parallel uploads, byte-range GETs for parallel downloads
- Transfer Acceleration uses edge locations for faster long-distance uploads
- CloudFront in front for repeated reads
Everyday CLI
$ aws s3 mb s3://my-unique-bucket-12345 --region af-south-1
$ aws s3 ls s3://my-unique-bucket-12345 --recursive --human-readable --summarize
$ aws s3 cp file.txt s3://my-unique-bucket-12345/
$ aws s3 sync ./site s3://my-unique-bucket-12345 --delete
$ aws s3 rm s3://my-unique-bucket-12345 --recursive
$ aws s3api put-bucket-versioning --bucket my-unique-bucket-12345 --versioning-configuration Status=Enabled
$ aws s3api list-object-versions --bucket my-unique-bucket-12345 --prefix report.pdf
aws s3 is the high-level, friendly command set; aws s3api exposes every API option.
Monitoring and Cost
- CloudTrail data events for object-level audit; server access logs for request logs
- Storage Lens and Storage Class Analysis show usage and savings
- Costs: storage (per class), requests, data transfer out, retrieval fees, lifecycle transitions, replication, KMS requests
- Savings: lifecycle rules, Intelligent-Tiering, delete old versions, abort multipart uploads, VPC gateway endpoint (free) instead of NAT
Common Mistakes
| Mistake | Fix |
|---|---|
| Public bucket | Block Public Access on; CloudFront with OAC |
| No lifecycle on logs | Transition and expire |
| Versioning with no noncurrent expiry | Expire old versions |
| One hot prefix | Distribute keys |
403 instead of 404 for missing keys |
Without s3:ListBucket S3 returns 403 for absent objects |
| Wrong Region endpoint / DNS delay on new buckets | Use the regional endpoint |
| Giant objects in one PUT | Multipart upload |