AWS S3: A Practical Guide for Backend Developers
AWS for Backend Developers
AWS for Backend Developers
AWS S3: A Practical Guide for Backend Developers
S3 is one of the first AWS services every backend developer should understand. It looks like “just file storage”, but it quietly powers uploads, exports, backups, logs, media, and async workflows.
Simple mental model:
S3 stores files. Your database stores information about those files.
What Is AWS S3?
Amazon S3, or Simple Storage Service, is AWS object storage. You can store and retrieve almost any amount of data from anywhere.
Use S3 for:
- User-uploaded images
- PDFs, resumes, invoices
- CSV exports and reports
- Logs and backups
- Videos and thumbnails
- Static frontend assets
Database = searchable app data
S3 = files and large objects
The Three Core Terms
1. Bucket
A bucket is the top-level container.
myapp-prod-uploads
myapp-prod-invoices
myapp-prod-assets
Bucket names are globally unique. If someone already owns backend, you cannot create another bucket named backend.
2. Object
An object is the actual file stored in S3.
3. Key
A key is the path-like name of the object.
users/42/avatar.png
invoices/2026/05/invoice-1001.pdf
exports/orders-2026-05-26.csv
S3 keys look like folders, but they are really strings. S3 is object storage, not a normal filesystem.
Important Features
- Scalability: S3 can handle huge amounts of data without you managing servers.
- Durability: S3 is designed for 99.999999999% durability.
- Security: Access is controlled using IAM, bucket policies, and encryption.
- Versioning: S3 can keep older versions of the same object.
- Lifecycle rules: S3 can move or delete files automatically to control cost.
- Events: S3 can trigger Lambda, SQS, SNS, or EventBridge when files change.
The Backend Upload Pattern
For large uploads, do not route the whole file through your backend unless needed.
Bad:
Browser -> Backend -> S3
Better:
Browser -> S3
Backend only authorizes the upload
This is done using a presigned URL.
A presigned URL is a temporary URL that allows one specific upload or download for a short time.
Upload Flow
1. Frontend asks backend for upload URL.
2. Backend checks auth.
3. Backend creates safe S3 key.
4. Backend returns presigned PUT URL.
5. Browser uploads directly to S3.
6. Backend stores key and metadata in DB.
Download Flow
1. User asks for a private file.
2. Backend checks ownership.
3. Backend returns presigned GET URL.
4. User downloads directly from S3.
What Goes In DB vs S3?
Store the file in S3:
users/42/resume/abc123.pdf
Store the file details in your database:
user_id: 42
file_key: users/42/resume/abc123.pdf
content_type: application/pdf
size: 245120
status: uploaded
This keeps your database lean and lets S3 do what it is built for.
Storage Classes
S3 has different storage classes based on how often the data is accessed.
- Standard: frequently accessed files
- Intelligent-Tiering: unknown or changing access patterns
- Standard-IA: rarely accessed but still needed quickly
- One Zone-IA: cheaper infrequent access in one availability zone
- Glacier: long-term archive
- Glacier Deep Archive: lowest-cost archive for rarely accessed data
If you are just starting, use Standard. Add lifecycle rules once you understand your access pattern.
Security Basics
For most backend apps, start private.
Private bucket
Block Public Access ON
Encryption ON
Access through IAM or presigned URLs
Common permissions:
s3:PutObject upload
s3:GetObject read/download
s3:DeleteObject delete
s3:ListBucket list objects
Give the backend only the permissions it needs. Do not give broad S3 access just because it is easier.
Lifecycle Rules
Lifecycle rules help you clean up or archive files automatically.
tmp/* -> delete after 1 day
exports/* -> delete after 14 days
logs/* -> cheaper storage after 30 days
backups/* -> archive after 90 days
This matters because forgotten files quietly become cost.
S3 Events
S3 can trigger work when a file is uploaded or deleted.
User uploads image
-> S3 event
-> Lambda creates thumbnail
-> Thumbnail saved back to S3
Useful for:
- Image resizing
- Virus scanning
- CSV import
- PDF processing
- Data pipeline triggers
Real Use Case: Image Upload Service
Imagine you are building an image hosting feature.
- User selects an image.
- Backend validates user and returns a presigned upload URL.
- Browser uploads the image directly to S3.
- S3 event triggers Lambda.
- Lambda creates thumbnails.
- CloudFront serves the images quickly to users.
Browser -> S3 -> Lambda -> S3
User -> CloudFront -> S3
Common Mistakes
- Making buckets public by default
- Storing files directly in the database
- Using user filenames as S3 keys
- Forgetting CORS for browser uploads
- Not deleting temporary files
- Giving the backend too much S3 permission
- Serving heavy public traffic directly from S3 instead of CloudFront
Final Mental Model
S3 stores files.
Database stores file metadata.
IAM controls access.
Presigned URLs give temporary permission.
Lifecycle rules control cost.
S3 events start async processing.
CloudFront delivers public files faster.
Once this clicks, S3 stops feeling like storage and starts feeling like a core backend building block.