Skip to content
AWS aws storage 6 min read

EBS vs EFS vs S3: When to Use Which

AWS gives you three main storage services, and beginners often pick the wrong one out of habit. Amazon EBS (Elastic Block Store) is a hard drive for one server. Amazon EFS (Elastic File System) is a shared folder that many servers can mount at once. Amazon S3 (Simple Storage Service) is a giant bucket for files (objects) that apps reach over the network. The single most important rule: pick storage by how your data is accessed, not by what feels familiar. This page gives you a clear rubric so you stop overpaying and stop hitting walls.

The 30-second rubric

Most decisions come down to one question: how many machines need the data, and how do they talk to it?

NeedUseWhy
A boot disk or a database volume for one instanceEBSBlock storage, lowest latency, attaches to a single instance
A POSIX file system that many instances read/write at the same timeEFSShared NFS file system, auto-scaling, mounts on many machines
Files an app fetches by name over HTTP(S) — assets, backups, logs, data lakesS3Object storage, virtually unlimited, cheapest per GB, internet-reachable

If you remember nothing else: one server = EBS, many servers as a folder = EFS, files-by-URL = S3.

Amazon EBS — a disk for a single instance

EBS gives an EC2 (Elastic Compute Cloud) instance a block device: it behaves exactly like a physical hard drive you can format, partition, and put a file system on. It lives in one Availability Zone (AZ) (a data center within a region) and attaches to one instance at a time.

When to use EBS: the operating system boot volume, a self-managed database (PostgreSQL, MySQL) that needs low, consistent latency, or any app that wants raw disk performance for a single host.

When NOT to use EBS: when several instances must share the same files. A standard EBS volume attaches to only one instance. (There is a “Multi-Attach” mode for io1/io2 volumes, but it requires a cluster-aware file system and is a niche tool — not a general “share files” answer. Reach for EFS instead.)

Create and attach a volume:

  1. Open the EC2 console -> Elastic Block Store -> Volumes -> Create volume.
  2. Pick a type (gp3 is the modern default), size (e.g. 100 GiB), and the same AZ as your instance.
  3. Select the new volume -> Actions -> Attach volume and choose your instance and device name.
aws ec2 create-volume \
  --availability-zone us-east-1a \
  --size 100 \
  --volume-type gp3

Output:

{
    "VolumeId": "vol-0a1b2c3d4e5f67890",
    "AvailabilityZone": "us-east-1a",
    "Size": 100,
    "VolumeType": "gp3",
    "State": "creating"
}
aws ec2 attach-volume \
  --volume-id vol-0a1b2c3d4e5f67890 \
  --instance-id i-0a1b2c3d4e5f \
  --device /dev/sdf

Cost note: gp3 is about $0.08/GB-month in us-east-1, so 100 GiB is roughly $8/month — and you pay for the provisioned size whether or not it is full.

Amazon EFS — a shared file system for many instances

EFS is a fully managed NFS (Network File System) file system. Many EC2 instances — even across multiple AZs — can mount the same EFS file system and see the same files at the same time, with standard POSIX permissions. It grows and shrinks automatically; you never provision a size.

When to use EFS: shared web content across an Auto Scaling group, a content management system with many app servers, CI/CD build caches, or any lift-and-shift app that expects a normal mounted directory shared between hosts.

When NOT to use EFS: when each file is really an independent object an app fetches by key (uploaded images, backups, static website files). That is an S3 pattern, and S3 is far cheaper. EFS is the most expensive of the three per GB, so do not use it as a dumping ground.

  1. Open the EFS console -> Create file system.
  2. Choose your VPC (Virtual Private Cloud — your private network, e.g. vpc-0a1b2c3d) and create mount targets in each subnet/AZ.
  3. On each instance, install the EFS utils and mount it.
aws efs create-file-system \
  --performance-mode generalPurpose \
  --encrypted \
  --tags Key=Name,Value=shared-app-data

Output:

{
    "FileSystemId": "fs-0a1b2c3d4e5f67890",
    "LifeCycleState": "creating",
    "PerformanceMode": "generalPurpose",
    "Encrypted": true
}

Mount it from an instance (the file system DNS name resolves inside your VPC):

sudo mount -t efs -o tls fs-0a1b2c3d4e5f67890:/ /mnt/shared

Cost note: EFS Standard is around $0.30/GB-month — roughly 4x EBS and 13x S3 Standard. Use EFS lifecycle management to move cold files to Infrequent Access automatically and cut cost dramatically.

Amazon S3 — object storage for files-by-name

S3 stores objects (a file plus metadata) inside buckets. You do not mount it like a disk; apps read and write objects by key over HTTPS using the AWS SDK or CLI. It is virtually unlimited, durable (11 nines), and the cheapest option per GB.

When to use S3: user uploads, images and video, static website assets, application logs, database backups, data lakes, and anything served via CloudFront or downloaded directly.

When NOT to use S3: as a live boot disk or a low-latency database volume. S3 is not a block device and is not a POSIX file system — there is no real “edit in place,” and you cannot install an OS on it.

  1. Open the S3 console -> Create bucket -> give it a globally unique name and a region.
  2. Leave Block all public access ON unless you have a specific reason to disable it.
  3. Upload objects via the console, SDK, or CLI.
aws s3 cp ./backup-2026-06-15.tar.gz s3://my-app-backups/backups/

Output:

upload: ./backup-2026-06-15.tar.gz to s3://my-app-backups/backups/backup-2026-06-15.tar.gz

Cost note: S3 Standard is about $0.023/GB-month, and you can drop cold data to Glacier classes for under $0.004/GB-month. This is why backups belong in S3, not on an oversized EBS volume.

The common mistakes

  • Reaching for EFS to “share files” when S3 fits. If your code uploads and downloads whole files by name, use S3 — it is simpler and ~13x cheaper. Only use EFS when something genuinely needs a mounted POSIX path shared between hosts.
  • Reaching for EBS when you need shared access. A standard EBS volume attaches to one instance. Two web servers cannot both mount the same EBS volume to share content — that is what EFS is for.
  • Using EFS as cheap bulk storage. It is the priciest per GB. Match the access pattern, not the habit.

Best practices

  • Decide by access pattern first: one host (EBS), many hosts sharing a folder (EFS), files-by-key (S3).
  • Default new EC2 volumes to gp3 and right-size them — you pay for provisioned size, not used size.
  • Turn on encryption at rest for all three (EBS, EFS, and S3 all support it with one flag).
  • Use EFS lifecycle management and S3 lifecycle policies to move cold data to cheaper tiers automatically.
  • Keep backups in S3 (or Glacier), never on large attached EBS volumes you forgot to delete.
  • Put EFS mount targets in every AZ your instances run in to avoid cross-AZ latency and single-AZ outages.
  • Before choosing EFS, ask “could this just be S3 objects?” — the answer is yes more often than people expect.
Last updated June 15, 2026
Was this helpful?