In This Guide
- What Is S3 and Why Does Everyone Use It
- Core Concepts: Buckets, Objects, Keys, and Versions
- S3 Storage Classes: Choosing the Right One
- S3 Security: Bucket Policies, ACLs, and Block Public Access
- Lifecycle Policies: Automate Cost Savings
- S3 Performance: Multipart Uploads and Transfer Acceleration
- Real Use Cases: What Developers Actually Store in S3
- Static Website Hosting with S3
- Frequently Asked Questions
Key Takeaways
- Infinitely scalable: S3 stores any amount of data — from a single file to exabytes. There is no capacity planning, no storage provisioning, and no size limits per bucket.
- 11 nines durability: AWS guarantees 99.999999999% durability for S3 Standard. That is 0.000000001% chance of data loss per year. In practice, S3 data loss from AWS-side failures is essentially unheard of.
- Storage classes matter: Moving infrequently accessed data from S3 Standard ($0.023/GB/month) to S3 Glacier Instant Retrieval ($0.004/GB/month) is an 83% cost reduction. Lifecycle policies automate this automatically.
- Security requires action: S3 buckets are private by default, but Block Public Access must be explicitly enabled to prevent accidental exposure. Always enable it at the account level.
S3 is the most used service in all of AWS, and it is the one most developers encounter first. It stores the images your web app serves, the backups your RDS database creates, the deployment artifacts your CI/CD pipeline produces, the access logs your API Gateway generates, and the static files your React app needs to load.
S3 looks simple — it is a bucket, you put files in it — but there are enough features, storage classes, security settings, and pricing nuances that a guide is worth reading before you touch production. Getting S3 wrong means either paying too much (wrong storage class, no lifecycle policies) or getting breached (misconfigured permissions, public buckets).
This guide covers everything from the basics to the advanced patterns that save money and keep data secure.
What Is S3 and Why Does Everyone Use It
Amazon S3 (Simple Storage Service) is an object storage service that stores any type of file — called an object — at any scale, with 99.999999999% durability, starting at $0.023 per GB per month. It is the foundation of the AWS ecosystem because virtually every other AWS service either reads from or writes to S3.
Unlike a file system (where you navigate a directory tree) or a block storage device (where you have a disk mounted to a server), S3 is an object store. Each object is identified by a unique key (effectively a file path), stored in a bucket (a named container), and accessible via an HTTPS URL or the AWS API.
Why S3 is used for almost everything:
- Unlimited scale: No capacity limits. One bucket can hold one file or one trillion files. You never provision storage.
- Durability by default: AWS automatically stores each object redundantly across multiple Availability Zones. You do not set up replication — it just happens.
- Native AWS integration: Lambda, RDS, Athena, CloudFront, CodeBuild, and dozens of other services have native S3 integration built in. S3 is the universal staging area of the AWS ecosystem.
- Cost-effective: $0.023 per GB per month for S3 Standard. For infrequently accessed data, storage classes drop below $0.01/GB. For archival data, Glacier Deep Archive is $0.00099/GB/month — sub-$1 per TB.
Core Concepts: Buckets, Objects, Keys, and Versions
Buckets are the top-level containers for S3 objects. Bucket names must be globally unique across all AWS accounts (not just your account). Bucket names are part of the S3 URL: https://my-bucket-name.s3.amazonaws.com/. Each bucket lives in one AWS region.
Objects are the individual files stored in S3. Each object can be up to 5 TB. Objects consist of the data itself plus metadata — the object's key, size, last modified timestamp, storage class, and any custom metadata you add.
Keys are the unique identifiers for objects within a bucket. Keys look like file paths (uploads/2026/03/photo.jpg) but S3 is a flat namespace — there are no real directories. The "/" character is a convention that tools use to display objects in a folder-like structure.
Versioning is an optional feature that stores every version of every object. When versioning is enabled, deleting an object adds a delete marker rather than removing the data. Previous versions remain accessible by version ID. Enable versioning on buckets that store important data that must be recoverable from accidental deletion or overwrite.
Object URLs follow the pattern:
# Path-style URL (being deprecated) https://s3.amazonaws.com/bucket-name/object-key # Virtual-hosted-style URL (current standard) https://bucket-name.s3.region.amazonaws.com/object-key # CloudFront CDN URL (for production web assets) https://d1234567890.cloudfront.net/object-key
S3 Storage Classes: Choosing the Right One
S3 offers eight storage classes with different pricing tiers for storage cost, retrieval cost, and retrieval latency. Choosing the right class for each type of data can reduce S3 storage costs by 60-90%.
| Storage Class | Use Case | Storage Cost/GB/mo | Retrieval | Min Duration |
|---|---|---|---|---|
| S3 Standard | Frequently accessed data | $0.023 | Immediate, free | None |
| S3 Intelligent-Tiering | Unknown access patterns | $0.023 (+ monitoring fee) | Immediate | None |
| S3 Standard-IA | Infrequently accessed, fast retrieval | $0.0125 | Immediate, $0.01/GB | 30 days |
| S3 One Zone-IA | Infrequent, non-critical, single AZ | $0.01 | Immediate, $0.01/GB | 30 days |
| S3 Glacier Instant | Archive with millisecond retrieval | $0.004 | Milliseconds, $0.03/GB | 90 days |
| S3 Glacier Flexible | Archive, 1-12 hour retrieval | $0.0036 | Minutes to hours | 90 days |
| S3 Glacier Deep Archive | Long-term archive, 12-48 hour retrieval | $0.00099 | 12-48 hours | 180 days |
The rule of thumb: Use Standard for data accessed more than once a month. Use Standard-IA for data accessed less than once a month but needed quickly. Use Glacier Instant for compliance archives that need sub-second retrieval. Use Glacier Deep Archive for regulatory data that must be kept for years but may never need to be accessed.
S3 Intelligent-Tiering monitors access patterns and automatically moves objects between Standard and IA tiers based on actual usage. It adds a small per-object monitoring fee ($0.0025 per 1,000 objects per month) but can be the right choice when you genuinely do not know access patterns in advance.
S3 Security: Bucket Policies, ACLs, and Block Public Access
Every S3 bucket should have Block Public Access enabled at the account level unless you are intentionally serving public static content. From there, use bucket policies to grant specific cross-account or service access and IAM roles to grant application access — never make individual objects public unless they are intended to be publicly accessible.
Block Public Access: Four settings that override any bucket or object ACL that would make data public. Enable all four at the account level in the S3 console. This single action prevents the most common S3 security mistake.
Bucket policies are JSON documents attached to a bucket that grant or deny access to principals (AWS accounts, IAM roles, AWS services). Example policy to allow CloudFront to read objects:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::123456789:distribution/DIST_ID"
}
}
}]
}This pattern — S3 private + CloudFront distribution with OAC (Origin Access Control) — is the standard architecture for serving S3 content to the public web securely.
Lifecycle Policies: Automate Cost Savings
S3 Lifecycle policies automatically transition objects between storage classes or delete them after a defined period. A well-configured lifecycle policy is the easiest way to reduce S3 costs without any ongoing maintenance.
Example lifecycle policy for an application log bucket:
- After 30 days: transition to S3 Standard-IA (access is infrequent after the first month)
- After 90 days: transition to S3 Glacier Flexible Retrieval (logs over 90 days old are rarely accessed)
- After 365 days: delete (logs over 1 year old have no business value)
For a bucket storing 1 TB of logs that grows by 50 GB/month, this policy can reduce annual S3 costs by 60-70% compared to leaving all logs in Standard storage.
Configure lifecycle policies in the S3 console under the bucket's Management tab, or via Terraform:
resource "aws_s3_bucket_lifecycle_configuration" "logs" { bucket = aws_s3_bucket.logs.id rule { id = "log_rotation" status = "Enabled" transition { days = 30 storage_class = "STANDARD_IA" } transition { days = 90 storage_class = "GLACIER" } expiration { days = 365 } } }
Real Use Cases: What Developers Actually Store in S3
Application assets: Images, videos, and documents uploaded by users. S3 + CloudFront is the standard architecture for serving user-uploaded media at scale. The application uploads to S3 directly (using pre-signed URLs to avoid routing through your application server) and CloudFront serves the content from the nearest edge location.
Static website hosting: React, Vue, and Angular apps are compiled to static HTML/CSS/JS files that can be served directly from S3. Combined with CloudFront and Route 53, this delivers a fast, cheap, globally distributed web application with no web servers to manage.
Database backups: RDS automated backups go to S3. Lifecycle policies archive old backups to Glacier. Cross-region replication copies critical backups to a second region for disaster recovery.
Data lake foundation: Raw CSV, JSON, and Parquet files from operational systems. Athena queries these files directly with SQL. Glue crawlers catalog the schema. This is the foundation of a modern data lake architecture without a managed cluster.
CI/CD artifacts: Build artifacts from CodeBuild, compiled Lambda packages, Docker images (ECR uses S3 under the hood). Deployment pipelines read from and write to S3 constantly.
Access and server logs: CloudFront access logs, S3 server access logs, ELB access logs, and VPC Flow Logs all go to S3. Query them with Athena or ship them to a SIEM for security analysis.
Static Website Hosting with S3
S3 static website hosting serves HTML files directly from a bucket. Combined with CloudFront for HTTPS and CDN caching, and Route 53 for custom domain routing, this is the standard way to host static sites and single-page applications at essentially zero cost for low-traffic sites.
Setup steps:
- Create an S3 bucket with the same name as your domain (e.g.,
www.example.com) - Upload your build output (
dist/orbuild/directory) to the bucket - Create a CloudFront distribution with the S3 bucket as the origin, using Origin Access Control
- Request an ACM certificate for your domain (free, auto-renewing)
- Attach the certificate to your CloudFront distribution
- Create a Route 53 alias record pointing your domain to the CloudFront distribution
Cost for a static site with 10,000 visitors/month: approximately $0.50-$2.00/month total (S3 storage + CloudFront data transfer + Route 53 hosted zone). Compare to $5-25/month for a managed hosting platform doing the same thing.
For React/Vue/Angular apps, add a CloudFront error page rule to redirect all 404s back to /index.html. This enables client-side routing to work correctly when a user bookmarks a deep link and navigates directly to it.
Frequently Asked Questions
How much does S3 storage cost?
S3 Standard costs $0.023 per GB per month in the US East (N. Virginia) region. Storing 100 GB costs $2.30/month. Data transfer out to the internet costs $0.09 per GB after the first 1 GB free per month. PUT, GET, and other request costs are fractions of a cent per 1,000 requests. Most small applications spend under $5/month on S3.
Is S3 a database?
No. S3 is an object store, not a database. You cannot query S3 objects with SQL (though Athena can query structured files stored in S3). S3 is optimized for storing and retrieving whole files, not for individual record lookups, updates, or transactions. Use DynamoDB or RDS for application data and S3 for files.
How do I make an S3 object publicly accessible?
Disable the bucket-level Block Public Access setting, then either set the object ACL to public-read or add a bucket policy that allows s3:GetObject for all principals (Principal: *). For serving web assets publicly, the recommended approach is to keep the bucket private and use CloudFront with Origin Access Control, which serves objects publicly through CloudFront without making the S3 bucket itself public.
What is the maximum file size in S3?
A single S3 object can be up to 5 TB. Files larger than 100 MB should be uploaded using the multipart upload API, which splits the file into parts (5 MB to 5 GB each) and uploads them in parallel. The AWS CLI and SDKs handle multipart uploads automatically for large files — you do not need to implement the multipart logic yourself.
S3 is the foundation of every AWS architecture. Get the skills.
Join professionals from Denver, NYC, Dallas, LA, and Chicago for two days of hands-on AI and tech training. $1,490. October 2026. Seats are limited.
Reserve Your SeatNote: Information in this article reflects the state of the field as of early 2026. Technology evolves rapidly — verify specific version numbers, pricing, and service availability directly with vendors before making decisions.