Skip to content

Storage

First PublishedByAtif Alam

AWS provides different storage types for different use cases. The three core services are S3 (object storage), EBS (block storage for EC2), and EFS (shared file storage).

ServiceTypeAccessUse Case
S3Object storageHTTP APIFiles, backups, static websites, data lakes
EBSBlock storageAttached to one EC2Databases, OS disks, high-performance I/O
EFSFile storage (NFS)Shared across EC2sShared config, CMS content, container storage

S3 stores data as objects (files) in buckets (containers). It’s designed for 99.999999999% (11 nines) durability — your data is essentially never lost.

┌─────────────────────────────────────────┐
│ Bucket: my-company-assets │
│ (globally unique name, region-specific)│
│ │
│ ├── images/ │
│ │ ├── logo.png (object) │
│ │ └── banner.jpg (object) │
│ ├── data/ │
│ │ └── report-2026.csv (object) │
│ └── index.html (object) │
└─────────────────────────────────────────┘
ConceptWhat It Is
BucketA container for objects. Name must be globally unique across all AWS accounts.
ObjectA file + metadata. Identified by a key (the full path, e.g. images/logo.png).
KeyThe “path” to an object within a bucket. S3 is flat — the / is just part of the key name, not a real directory.
MetadataKey-value pairs attached to an object (content type, custom headers, etc.).
Object size0 bytes to 5 TB per object. Use multipart upload for files > 100 MB.
Terminal window
# Create a bucket
aws s3 mb s3://my-unique-bucket-name
# Upload a file
aws s3 cp report.csv s3://my-bucket/data/report.csv
# List objects
aws s3 ls s3://my-bucket/data/
# Download
aws s3 cp s3://my-bucket/data/report.csv ./local-report.csv
# Sync a directory (like rsync)
aws s3 sync ./local-dir s3://my-bucket/backup/
# Delete
aws s3 rm s3://my-bucket/data/old-report.csv
# Delete a bucket (must be empty)
aws s3 rb s3://my-bucket

S3 offers different storage classes that trade access speed for cost:

Storage ClassAccessRetrieval FeeMonthly Cost (per GB)Use Case
S3 StandardInstantNone~$0.023Frequently accessed data
S3 Standard-IAInstantPer-GB fee~$0.0125Infrequent access (backups, older data)
S3 One Zone-IAInstantPer-GB fee~$0.010Infrequent, non-critical (can recreate)
S3 Glacier InstantInstantPer-GB fee~$0.004Archive with instant access
S3 Glacier FlexibleMinutes to hoursPer-GB fee~$0.0036Archive (compliance, long-term backup)
S3 Glacier Deep Archive12–48 hoursPer-GB fee~$0.00099Rarely accessed archive
S3 Intelligent-TieringAutomaticNone~$0.023 + monitoring feeUnknown access patterns

Automatically move objects between storage classes or delete them:

{
"Rules": [{
"ID": "archive-old-logs",
"Status": "Enabled",
"Filter": {"Prefix": "logs/"},
"Transitions": [
{"Days": 30, "StorageClass": "STANDARD_IA"},
{"Days": 90, "StorageClass": "GLACIER_IR"},
{"Days": 365, "StorageClass": "DEEP_ARCHIVE"}
],
"Expiration": {"Days": 730}
}]
}

This moves logs to cheaper storage over time and deletes them after 2 years.

Versioning keeps every version of every object. When you overwrite or delete a file, previous versions are preserved.

Terminal window
# Enable versioning
aws s3api put-bucket-versioning --bucket my-bucket \
--versioning-configuration Status=Enabled
# List versions
aws s3api list-object-versions --bucket my-bucket --prefix data/report.csv
  • Protects against accidental deletion — delete adds a “delete marker”; the object can be restored.
  • Increases storage cost — old versions consume space. Use lifecycle rules to expire old versions.

Bucket policies (JSON, like IAM policies) control access at the bucket level:

{
"Version": "2012-10-17",
"Statement": [{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-website-bucket/*"
}]
}

Best practice: Use bucket policies and IAM policies. Avoid ACLs (legacy, harder to manage). Block public access by default — enable it only when intentional (static websites).

S3 can serve a static website (HTML, CSS, JS):

Terminal window
# Enable website hosting
aws s3 website s3://my-website-bucket \
--index-document index.html --error-document error.html

Access at: http://my-website-bucket.s3-website-us-east-1.amazonaws.com

For production, put CloudFront (CDN) in front for HTTPS, caching, and a custom domain.

PracticeWhy
Block public access (default)Prevent accidental data leaks
Enable versioningProtect against accidental deletes
Enable server-side encryption (SSE-S3 or SSE-KMS)Encrypt data at rest
Use VPC endpoints for private accessS3 traffic doesn’t leave the AWS network
Enable access loggingAudit who accessed what

EBS provides block-level storage volumes for EC2 instances. Think of an EBS volume as a virtual hard drive.

TypeCodePerformanceUse Case
General Purpose SSDgp33,000–16,000 IOPSBoot volumes, dev/test, most workloads
Provisioned IOPS SSDio2Up to 256,000 IOPSDatabases (MySQL, PostgreSQL, Oracle)
Throughput Optimized HDDst1500 MB/s throughputBig data, log processing, data warehouses
Cold HDDsc1250 MB/s throughputInfrequent access, lowest cost

gp3 is the default choice for most workloads — good performance at a reasonable price.

FeatureDetail
AttachmentOne EC2 instance at a time (except io2 with multi-attach)
AZ-boundA volume exists in one AZ; must be in the same AZ as the EC2 instance
SnapshotsPoint-in-time backup to S3. Incremental (only changed blocks). Can copy across regions.
EncryptionAES-256, managed by KMS. Enable by default via account-level setting.
Size1 GB – 64 TB
Terminal window
# Create a volume
aws ec2 create-volume --volume-type gp3 --size 100 --availability-zone us-east-1a
# Attach to an instance
aws ec2 attach-volume --volume-id vol-abc --instance-id i-xyz --device /dev/sdf
# Create a snapshot
aws ec2 create-snapshot --volume-id vol-abc --description "Before upgrade"
# Create a volume from a snapshot (even in a different AZ)
aws ec2 create-volume --snapshot-id snap-abc --availability-zone us-east-1b

EFS is a managed NFS file system that can be mounted by multiple EC2 instances simultaneously — useful for shared storage.

EBSEFS
ProtocolBlock (attached to one instance)NFS (mounted by many instances)
AZ scopeSingle AZMulti-AZ (regional)
ScalingFixed size (set at creation, can resize)Auto-scales (pay for what you use)
PerformanceVery high IOPS (io2)Good throughput, higher latency than EBS
Best forDatabases, boot volumesShared config, CMS, container storage
Terminal window
# Install NFS client
sudo yum install -y amazon-efs-utils
# Mount the file system
sudo mount -t efs fs-abc123:/ /mnt/efs
# Add to /etc/fstab for auto-mount on reboot
echo "fs-abc123:/ /mnt/efs efs defaults,_netdev 0 0" | sudo tee -a /etc/fstab
ClassCostUse Case
StandardHigherFrequently accessed files
Infrequent Access (IA)Lower + retrieval feeFiles accessed less than once a month

Use lifecycle management to move files to IA automatically after N days.

QuestionAnswer
Storing files accessed via HTTP/API?S3
Need a disk for an EC2 instance?EBS
Need shared storage across multiple EC2s?EFS
Long-term archive (compliance, backups)?S3 Glacier
High-performance database storage?EBS io2
Container shared storage (ECS/EKS)?EFS
  • S3 is object storage for files, backups, and static websites. Use lifecycle policies to move data to cheaper tiers automatically.
  • EBS is block storage attached to a single EC2 instance. Use gp3 for most workloads, io2 for databases.
  • EFS is shared NFS storage across multiple instances. Auto-scales and is regional (multi-AZ).
  • Always enable encryption and versioning (S3) or snapshots (EBS) for data protection.
  • Use S3 Intelligent-Tiering when you don’t know the access pattern; use explicit storage classes when you do.