S3: Object Storage
Amazon Simple Storage Service (S3) is object storage built for the internet - virtually unlimited capacity, accessible over HTTPS, and the storage backbone behind countless applications. It stores anything from website assets and backups to data-lake analytics and machine-learning datasets.
Buckets and objects
S3 has a flat structure built from two concepts:
- Bucket — a globally unique, region-scoped container for objects. The name must be unique across all of AWS.
- Object — a file plus metadata, identified by a key (its full name). Keys can contain
/, which the console renders as folders, but the namespace is actually flat - there are no real directories.
Objects can be up to 5 TB; use multipart upload for anything over 100 MB to improve throughput and resilience.
Durability and availability
S3 Standard is designed for eleven nines (99.999999999%) of durability - achieved by redundantly storing each object across multiple devices in multiple AZs within a Region. Availability (the SLA for access) is lower and varies by storage class, typically 99.9%-99.99%.
Durability is not backup. S3 protects against hardware failure, but a bad
aws s3 rmor a compromised credential can still delete your data. Enable versioning and consider Object Lock for true protection.
Storage classes
Choosing the right class is the primary S3 cost lever. All offer the same 11-nines durability.
| Class | Best for | Retrieval | Relative cost |
|---|---|---|---|
| Standard | Hot, frequently accessed data | Instant | Highest |
| Intelligent-Tiering | Unknown/changing access patterns | Instant | Auto-optimized |
| Standard-IA | Infrequent access, fast when needed | Instant (+ fee) | Lower |
| One Zone-IA | Re-creatable infrequent data | Instant (single AZ) | Lower still |
| Glacier Instant | Archive needing ms retrieval | Instant | Low |
| Glacier Flexible / Deep Archive | Long-term archive, compliance | Minutes to hours | Lowest |
Intelligent-Tiering is the safe default when you can’t predict access patterns - it moves objects between tiers automatically for a tiny monitoring fee and avoids retrieval surprises.
Versioning
Versioning keeps every version of an object, so overwrites and deletes are recoverable. A “delete” simply adds a delete marker; the prior versions remain.
aws s3api put-bucket-versioning \
--bucket devcraftly-uploads \
--versioning-configuration Status=Enabled
Versioning stores - and bills you for - every version. Without lifecycle rules to expire old versions, costs creep up silently over time.
Lifecycle policies
Lifecycle rules automate transitions between storage classes and expiration of objects or old versions.
{
"Rules": [
{
"ID": "ArchiveThenDelete",
"Status": "Enabled",
"Filter": { "Prefix": "logs/" },
"Transitions": [
{ "Days": 30, "StorageClass": "STANDARD_IA" },
{ "Days": 90, "StorageClass": "GLACIER" }
],
"Expiration": { "Days": 365 }
}
]
}
Bucket policies vs ACLs
Two mechanisms control access; modern practice is decisive about which to use.
| Mechanism | Granularity | Recommendation |
|---|---|---|
| Bucket policy (IAM-style JSON) | Bucket / prefix / object | Preferred - expressive, auditable |
| ACL (legacy) | Bucket / object | Avoid - disable via Object Ownership |
| IAM policy | On the principal | Use for per-user/role access |
Enable S3 Block Public Access at the account level and disable ACLs. The most common AWS data leak is an accidentally public bucket - block public access unless you have a deliberate, specific reason to allow it.
A bucket policy granting public read for a static site:
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::devcraftly-site/*"
}]
}
Static website hosting
S3 can serve a static site directly, though pairing it with CloudFront adds HTTPS, caching, and a custom domain.
aws s3 website s3://devcraftly-site/ \
--index-document index.html \
--error-document 404.html
CLI upload example
# Sync a local build folder to a bucket, deleting removed files
aws s3 sync ./dist s3://devcraftly-site --delete
Output:
upload: dist/index.html to s3://devcraftly-site/index.html
upload: dist/assets/app.css to s3://devcraftly-site/assets/app.css
upload: dist/assets/app.js to s3://devcraftly-site/assets/app.js
Best Practices
- Turn on Block Public Access and disable ACLs; control access with bucket and IAM policies.
- Enable versioning plus lifecycle rules to expire old versions and control cost.
- Use default encryption (SSE-S3 or SSE-KMS) on every bucket.
- Front public content with CloudFront for HTTPS, caching, and lower egress cost.
- Match data to the right storage class; use Intelligent-Tiering when access is unpredictable.
- Enable access logging or CloudTrail data events for audit, and tag buckets for cost allocation.