COMPARISON

AWS S3 vs EFS vs EBS — Choosing the Right Storage Service

By Akshay Ghalme·April 3, 2026·9 min read

Use S3 for object storage (images, backups, static files, data lakes). Use EBS for block storage attached to a single EC2 instance (databases, OS volumes). Use EFS for shared file storage that multiple instances or containers need to access simultaneously. S3 is cheapest at $0.023/GB, EBS gp3 costs $0.08/GB, and EFS Standard costs $0.30/GB — but each solves a fundamentally different problem.

AWS has three core storage services and picking the wrong one costs you either money, performance, or architectural headaches. I have seen teams store database files on S3 (terrible performance), use EBS for static assets (expensive and not scalable), and avoid EFS because it "costs too much" while manually syncing files between instances with rsync (a nightmare).

Each service exists for a specific reason. Here is when to use each.

Quick Comparison Table

FeatureS3EBSEFS
TypeObject storageBlock storageFile storage (NFS)
AccessHTTP API (GET, PUT)Attached to 1 EC2Mount on multiple EC2/containers
LatencyMillisecondsMicrosecondsLow milliseconds
Max sizeUnlimited64 TB per volumeUnlimited (petabyte scale)
Multi-instanceYes (via API)No (1 instance)Yes (thousands)
Cost (GB/month)$0.023$0.08 (gp3)$0.30 (Standard)
Durability99.999999999% (11 nines)99.999%99.999999999%
Best forFiles, backups, static sitesDatabases, OS volumesShared config, CMS, home dirs

S3 — Object Storage

S3 stores files as objects — each object has a key (path), the data itself, and metadata. You access objects through HTTP API calls, not filesystem operations. You cannot "mount" S3 as a drive.

When to use S3

  • Static website hosting — HTML, CSS, JS, images served via CloudFront CDN
  • Application file uploads — user avatars, documents, media files
  • Backups and archives — database dumps, log archives, compliance data
  • Data lakes — raw data for analytics, Athena queries, Spark jobs
  • Terraform state filesremote state storage
  • Docker images in ECR — ECR uses S3 under the hood

When NOT to use S3

  • Databases — S3 has millisecond latency per request. Databases need microsecond latency. Use EBS.
  • Application runtime data — if your app reads/writes files with filesystem calls (open, read, write, close), S3 does not support this. Use EBS or EFS.
  • Shared filesystem between instances — you would need to build your own sync mechanism. Use EFS instead.

S3 storage classes and cost

S3 Standard:            $0.023/GB/month  — frequently accessed data
S3 Intelligent-Tiering: $0.023/GB/month  — auto-moves between tiers
S3 Standard-IA:         $0.0125/GB/month — infrequent access, lower storage cost
S3 Glacier Instant:     $0.004/GB/month  — archive, millisecond retrieval
S3 Glacier Deep:        $0.00099/GB/month — cheapest, 12-hour retrieval

Use lifecycle policies to automatically move older data to cheaper tiers. Most teams save 40-60% on S3 costs by setting up lifecycle rules that move objects to Standard-IA after 30 days and Glacier after 90 days.

EBS — Block Storage

EBS provides virtual hard drives that attach to EC2 instances. It is block-level storage — your operating system sees it as a disk and formats it with a filesystem (ext4, xfs). It provides the lowest latency of the three.

When to use EBS

  • Database storageRDS uses EBS under the hood, and self-managed databases need EBS for data files
  • EC2 root volumes — the boot disk for your instances
  • Application data that needs fast I/O — log processing, video encoding, build environments
  • Any workload requiring consistent, low-latency storage

When NOT to use EBS

  • Sharing data between instances — a standard EBS volume attaches to one instance only. If you need shared storage, use EFS.
  • Storing large amounts of infrequently accessed data — EBS costs $0.08/GB even for data you rarely read. Move it to S3.
  • Static file serving — do not serve images or downloads from EBS. Use S3 + CloudFront.

EBS volume types

gp3:  $0.08/GB  — 3000 IOPS baseline, general purpose (USE THIS for most workloads)
gp2:  $0.10/GB  — IOPS tied to size (legacy, no reason to use for new volumes)
io2:  $0.125/GB — up to 64,000 IOPS, for high-performance databases
st1:  $0.045/GB — throughput-optimized HDD, for big data/streaming
sc1:  $0.015/GB — cold HDD, cheapest, for infrequent access
Always use gp3 instead of gp2 for new volumes. gp3 is 20% cheaper and gives you 3000 IOPS baseline regardless of volume size. gp2 ties IOPS to storage size — you need 1 TB just to get 3000 IOPS. I covered this in detail in the production RDS guide.

EFS — File Storage

EFS is a managed NFS (Network File System). You mount it on multiple EC2 instances or containers simultaneously, and they all read and write to the same files. It grows and shrinks automatically — you do not provision a size upfront.

When to use EFS

  • Shared application files — multiple instances serving the same content (WordPress, Drupal)
  • Shared configuration — config files that all instances need to read
  • Container shared storageECS Fargate tasks sharing files across containers
  • Machine learning training data — multiple GPU instances reading the same dataset
  • Home directories — user home dirs shared across a fleet of instances

When NOT to use EFS

  • Database storage — EFS latency is too high for database workloads. Use EBS.
  • Single-instance workloads — if only one instance needs the storage, EBS is 4x cheaper.
  • Large file archives — use S3 instead. EFS Standard costs $0.30/GB versus S3 at $0.023/GB.

EFS cost optimization

EFS Standard:           $0.30/GB/month  — frequently accessed
EFS Infrequent Access:  $0.016/GB/month — 87% cheaper for rarely accessed files
EFS Archive:            $0.008/GB/month — even cheaper for long-term storage

Enable EFS lifecycle policies to automatically move files to Infrequent Access after 30 days of no access. This alone can cut EFS costs by 50-70% for most workloads because a large portion of files on any filesystem are rarely accessed.

Real-World Architecture Example

Here is how a typical production application uses all three:

┌─────────────────────────────────────────────┐
│                Application                   │
├──────────────┬──────────────┬────────────────┤
│     S3       │     EBS      │      EFS       │
│              │              │                │
│ User uploads │ RDS database │ Shared config  │
│ Static assets│ EC2 root vol │ App logs       │
│ Backups      │ Build cache  │ WordPress media│
│ Terraform    │ Local scratch│ ML datasets    │
│ state files  │              │                │
│              │              │                │
│ $0.023/GB    │ $0.08/GB     │ $0.30/GB       │
│ Unlimited    │ 64TB max     │ Unlimited      │
│ HTTP API     │ 1 instance   │ Multi-instance │
└──────────────┴──────────────┴────────────────┘

Decision Flowchart

Ask yourself these questions in order:

  1. Do multiple instances need to access the same files simultaneously?EFS
  2. Does your application need a POSIX filesystem (open, read, write, close)?EBS (single instance) or EFS (multi-instance)
  3. Is this a database?EBS gp3 (or io2 for high-performance databases)
  4. Is this for storing files accessed via API (uploads, downloads, backups)?S3
  5. Is cost the primary concern and the data is rarely accessed?S3 Glacier or EFS Infrequent Access

Common Mistakes

  1. Using EBS for static file serving. Putting images and downloads on EBS means they are only accessible from one instance. Use S3 + CloudFront for global delivery at a fraction of the cost.
  2. Using EFS when only one instance needs storage. EFS costs 4x more than EBS gp3. If only one instance reads and writes the data, EBS is the right choice.
  3. Not using S3 lifecycle policies. Storing years of logs in S3 Standard when they could be in Glacier. Set up lifecycle rules — 30 days to IA, 90 days to Glacier.
  4. Using gp2 instead of gp3. No reason for this on new volumes. gp3 is cheaper and gives better baseline performance.
  5. Trying to use S3 as a filesystem. S3 is object storage with HTTP API access. If your app needs open/read/write/close operations, it needs EBS or EFS, not S3.

Frequently Asked Questions

When should I use S3 vs EBS vs EFS?

S3 for files accessed via API (uploads, backups, static assets). EBS for single-instance block storage (databases, OS volumes). EFS when multiple instances need shared filesystem access.

Which is cheapest?

S3 at $0.023/GB for Standard, $0.004/GB for Glacier. EBS gp3 at $0.08/GB. EFS Standard at $0.30/GB but drops to $0.016/GB with Infrequent Access lifecycle policies.

Can I attach EBS to multiple instances?

Standard EBS volumes attach to one instance only. Multi-Attach exists for io1/io2 but requires application-level coordination. For shared storage, use EFS.

Is S3 faster than EBS?

No. EBS provides microsecond latency (block-level, directly attached). S3 has millisecond latency (HTTP API). Use EBS for databases and latency-sensitive workloads.

Can I use S3 as a filesystem?

Not natively. S3 is object storage accessed via HTTP. Tools like s3fs-fuse exist but add latency. If you need a filesystem, use EBS or EFS.


Put It Into Practice

Most architectures use all three services for different purposes. Set up your VPC first, then deploy your RDS on EBS, serve your static assets from S3 + CloudFront, and use EFS if your containers or instances need shared file access.

Understanding which storage to use where is a fundamental AWS skill. Get this right and you save money, improve performance, and avoid architectural rework later.

AG

Akshay Ghalme

AWS DevOps Engineer with 3+ years building production cloud infrastructure. AWS Certified Solutions Architect. Currently managing a multi-tenant SaaS platform serving 1000+ customers.

More Guides & Terraform Modules

Every guide comes with a matching open-source Terraform module you can deploy right away.