Amazon S3
Has Demo
Simple Storage Service - Store and retrieve any amount of data
💵 Cost: S3 Free Tier includes 5GB storage, 20,000 GET, 2,000 PUT requests/month for 12 months. Empty buckets cost nothing. Delete all objects before deleting a bucket. See our Costs & Cleanup Guide for cleanup steps.
What is S3?
Amazon Simple Storage Service (S3) is object storage for the cloud. Think of it as an unlimited hard drive accessible from anywhere via HTTP. Store files, images, videos, backups, logs - anything you need.
S3 is Everywhere
S3 is one of the most used AWS services. Its used for static website hosting, data lakes, backup storage, content distribution, and much more. Understanding S3 is fundamental to working with AWS.
S3 Concepts
| Concept | Description | Example |
|---|---|---|
| Bucket | Container for objects (like a folder) | my-app-uploads |
| Object | File + metadata | users/123/avatar.jpg |
| Key | Unique identifier for an object | uploads/2024/01/report.pdf |
| Prefix | Key path for organization (like folders) | uploads/2024/01/ |
Create a Bucket
Terminal
$aws s3 mb s3://my-unique-bucket-name-12345 --region ap-southeast-1
make_bucket: my-unique-bucket-name-12345
Bucket Names are Global
S3 bucket names must be globally unique across ALL AWS accounts. Use your company name or project as a prefix to avoid conflicts.
Upload a File
TypeScript
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"
const s3 = new S3Client({ region: process.env.AWS_REGION })
export async function uploadFile(
file: Buffer,
key: string,
contentType: string
) {
const command = new PutObjectCommand({
Bucket: process.env.S3_BUCKET_NAME,
Key: key,
Body: file,
ContentType: contentType
})
await s3.send(command)
return `https://${process.env.S3_BUCKET_NAME}.s3.amazonaws.com/${key}`
}List Objects
TypeScript
import { ListObjectsV2Command } from "@aws-sdk/client-s3"
export async function listFiles(prefix?: string) {
const command = new ListObjectsV2Command({
Bucket: process.env.S3_BUCKET_NAME,
Prefix: prefix,
MaxKeys: 100
})
const response = await s3.send(command)
return response.Contents?.map(obj => ({
key: obj.Key,
size: obj.Size,
lastModified: obj.LastModified
})) ?? []
}Generate Presigned URL
Presigned URLs allow temporary access to private objects without exposing credentials:
TypeScript
import { GetObjectCommand } from "@aws-sdk/client-s3"
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"
export async function getDownloadUrl(key: string) {
const command = new GetObjectCommand({
Bucket: process.env.S3_BUCKET_NAME,
Key: key
})
// URL valid for 1 hour
const url = await getSignedUrl(s3, command, { expiresIn: 3600 })
return url
}Try the Demo
Check out the live S3 demo to upload files, list bucket contents, and generate download links.
Storage Classes
| Class | Use Case | Cost |
|---|---|---|
| Standard | Frequently accessed data | $0.023/GB |
| Intelligent-Tiering | Unknown access patterns | Auto-optimized |
| Glacier | Archive (retrieval in minutes) | $0.004/GB |
| Glacier Deep Archive | Long-term archive (retrieval in hours) | $0.00099/GB |
S3 Pricing
Region-Specific Pricing
Prices shown are for ap-southeast-1 (Singapore). Prices vary by region. Always verify at aws.amazon.com/s3/pricing. Last verified: January 2026.
| Component | Cost (ap-southeast-1) |
|---|---|
| Storage (Standard) | $0.023/GB/month |
| PUT/POST requests | $0.005 per 1,000 |
| GET requests | $0.0004 per 1,000 |
| Data transfer out | $0.09/GB (first 10TB) |
Cost Optimization
For images and static assets, use CloudFront CDN in front of S3. This reduces S3 request costs and speeds up delivery globally.