Skip to content

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