Amazon EBS in Depth: Block Storage, and How It Compares to S3 and EFS
Pick the wrong AWS storage service and you pay twice: in dollars and in rework. EBS is network-attached block storage for EC2 and Kubernetes nodes. S3 is object storage for assets, lakes, and backups at internet scale. EFS is a managed NFS file system many instances can share. They are not interchangeable—this post explains what each one is under the hood, when to use it, and how to choose with confidence.
In short
EBS = one disk-like volume per attachment zone, low latency, POSIX on a single instance (or multi-attach on specific types). S3 = key/object store, virtually unlimited, accessed over HTTP/API, eventual consistency models vary by operation. EFS = shared files across AZs in a region, NFS semantics, scales capacity automatically. Databases and boot volumes → EBS; static assets and data lakes → S3; shared config/content across many servers → EFS.
The three storage models on AWS
Every storage product answers two questions: what abstraction does the application see? and how is data reached?
| Service | Model | Protocol / API | Typical consumer |
|---|---|---|---|
| EBS | Block (raw sectors) | Attached to EC2 as /dev/xvdf; you format ext4, xfs, NTFS |
OS, databases, swap, container images on node disk |
| S3 | Object (bucket + key + metadata) | REST API, SDKs, s3:// URIs | Web assets, backups, analytics, ML datasets |
| EFS | File (directories, files, permissions) | NFSv4.1 (mount efs-dns:/) |
Shared uploads, CMS content, legacy apps expecting NFS |
Block storage does not know about files—your OS creates a filesystem on top. Object storage does not have a traditional “folder” hierarchy (prefixes are a convenience). File storage gives you paths and locks multiple hosts can use—if the application and protocol support it.
Amazon EBS: what it really is
Amazon Elastic Block Store (EBS) provides durable block-level volumes in a single Availability Zone (AZ). A volume is a replicated storage entity in that AZ; AWS manages the hardware and replication so you manage mount points and filesystems.
Lifecycle: create, attach, use, snapshot, delete
- Create — Empty volume or restored from snapshot; size and type are fixed at creation (expansion is supported later for most types).
- Attach — Bound to an EC2 instance in the same AZ as the volume. Cross-AZ attach is not supported for standard use.
- Initialize — First-touch on restored or new large volumes can cause latency spikes; use Fast Snapshot Restore or pre-warm for latency-sensitive workloads.
- Snapshot — Point-in-time backup to S3 (incremental, stored in AWS-managed buckets you do not administer).
- Detach / delete — Detach cleanly when possible; delete volume when no longer needed. Orphaned volumes are a classic FinOps leak—see FinOps + GreenOps (architect view).
Volume types (the decision that sticks)
EBS splits into SSD-backed (general and IOPS-focused) and HDD-backed (throughput-focused). Choose by IOPS, throughput, and cost—not by habit.
| Type | Use case | Performance shape | Notes |
|---|---|---|---|
| gp3 | Default for boot and most workloads | 3,000 IOPS and 125 MiB/s baseline; provision IOPS/throughput independently | Usually cheaper and more flexible than gp2; prefer for new volumes |
| gp2 | Legacy general purpose | IOPS scales with size (3 IOPS/GiB, burst credits on small volumes) | Migrate to gp3 when resizing or refactoring |
| io2 Block Express / io2 | OLTP databases, latency-sensitive apps | Up to 256,000 IOPS (io2 Block Express), 99.999% durability SLA on io2 | Highest cost; justify with measured IOPS needs |
| st1 | Big data, log processing, streaming reads | Throughput-optimized HDD; cannot be boot volume | Cheaper $/GB; not for random small I/O |
| sc1 | Cold, infrequently accessed throughput workloads | Lowest HDD cost; lowest throughput tier | Rarely right for production databases |
Provisioned IOPS vs throughput: On gp3 and io volumes you pay for configured IOPS and MB/s. Oversizing wastes money; undersizing causes queue depth and latency. Use CloudWatch metrics VolumeReadOps, VolumeWriteOps, VolumeQueueLength, and VolumeThroughputPercentage before upgrading to io2.
Durability, AZ binding, and Multi-Attach
- AZ scope — An EBS volume lives in one AZ. If that AZ has an impairment, you fail over by snapshot/restore or replication into another AZ—not by “moving” the same volume.
- Replication — AWS replicates within the AZ infrastructure; your snapshot is the cross-region/cross-AZ portability mechanism.
- Multi-Attach —
io1/io2only: one volume attached to multiple instances in the same AZ. Requires a cluster-aware filesystem (e.g. GFS2, OCFS2)—not a default ext4 on two Linux boxes (that corrupts data).
Snapshots and AMIs
EBS snapshots are the bridge between block storage and the rest of AWS:
- Incremental — Only changed blocks since the last snapshot are stored; cost grows with churn, not full size every time.
- Crash-consistent by default — For databases, quiesce or use VSS/agent for application-consistent snapshots.
- AMI baking — Launch templates and Auto Scaling often come from AMIs backed by snapshots of root volumes.
- Cross-region copy — Disaster recovery and DR drills; watch data transfer charges.
Snapshot data physically resides in S3’s infrastructure, but you interact through the EC2 snapshot API—not as public S3 objects you list in a bucket.
Encryption
Enable encryption by default at the account/Region level. EBS uses KMS keys (AWS-managed or customer-managed CMK). Encryption applies to volumes, snapshots, and volumes created from encrypted snapshots. Performance impact is negligible on modern instance types. Combine with tight KMS key policies and CloudTrail for audit.
Instance store vs EBS
Some instance families include instance store (local NVMe). It is physically attached to the host: very fast, but ephemeral if the instance stops or is terminated (with exceptions for stop/start behavior on Nitro—still plan for loss). Use instance store for scratch, caches, and temporary shuffle; use EBS for anything that must survive instance replacement.
Amazon S3: object storage in depth
Amazon S3 stores objects (up to 5 TiB per object in standard storage) in buckets. There is no “attach” step—applications call the API. That decoupling is why S3 scales to virtually unlimited data and request rates (with prefix design for very hot keys). For a dedicated S3-only guide—storage classes, replication, Object Lock, events, and operations—see Amazon S3 in depth.
Core concepts
- Bucket — Global unique name; lives in a Region; you choose where data resides for compliance.
- Key — Full path-like identifier (
reports/2026/q1/summary.parquet). - Storage class — Standard, Intelligent-Tiering, Standard-IA, One Zone-IA, Glacier Instant/Flexible/Deep Archive. Lifecycle policies transition objects automatically.
- Versioning — Protects against overwrite and delete mistakes; increases storage when objects churn.
- MFA Delete — Extra guardrail for versioned bucket deletes.
Consistency and performance
S3 provides strong read-after-write consistency for new objects and overwrites in all Regions today—a historical caveat exam questions loved is largely outdated for new designs. Performance tuning means:
- Prefix spread — Randomize hot key prefixes for extreme parallel workloads (historical 3,500 PUT/s per prefix guidance has evolved—still avoid single-key hotspots).
- Transfer Acceleration / CloudFront — For global uploads and downloads.
- S3 Express One Zone — Millisecond latency for frequently accessed data in a single AZ when you need object semantics with lower latency than cross-AZ standard S3.
Security and access patterns
- Block public access — Account-level settings first.
- IAM and bucket policies — Identity-based plus resource-based; Condition keys for TLS, IP, VPC endpoints.
- SSE-S3, SSE-KMS, SSE-C — Encryption at rest; KMS for audit and key rotation control.
- VPC endpoints (Gateway) — Keep traffic off the public internet and reduce NAT costs for high-volume S3 access from private subnets—pairs well with VPC endpoint strategy.
What S3 is bad at
S3 is not a POSIX filesystem for a database’s random 8 KiB writes. You do not “mount” standard S3 as /var/lib/mysql without an adapter (Mountpoint for Amazon S3, s3fs, or application-level SDK access)—and those patterns suit specific access shapes, not generic transactional DB storage. Latency is milliseconds over the network API, not microseconds on attached NVMe.
Amazon EFS: managed NFS in depth
Amazon Elastic File System (EFS) is a regional, elastic, fully managed NFSv4 file system. Many EC2 instances, Lambda functions (with EFS mount targets), and ECS tasks can mount the same file system concurrently.
Performance modes and classes
- Regional EFS — Replicates across AZs in the Region; mount targets in each AZ for low-latency local access.
- One Zone EFS — Lower cost; data in a single AZ—understand availability trade-offs.
- Throughput modes — Bursting (ties throughput to size), Provisioned (fixed MB/s), Elastic (scales with workload—common default for variable traffic).
- EFS Intelligent-Tiering — Moves files not accessed for a period to Infrequent Access storage class automatically.
Semantics that matter
- POSIX-ish — File locks, permissions, append—good for shared content, bad fit for latency-sensitive DB data compared to local EBS.
- ReadWriteMany in Kubernetes — EFS CSI driver enables
ReadWriteManyPVCs; EBS is typicallyReadWriteOnceper node. See Kubernetes storage (PV, PVC, StorageClass) and CRI vs CSI deep dive. - Security — Security groups on mount targets, IAM authorization for NFS clients, encryption in transit and at rest.
Head-to-head comparison
Abstraction and access
| Dimension | EBS | S3 | EFS |
|---|---|---|---|
| Unit of storage | Volume (sectors) | Object (key + bytes + metadata) | File + directory tree |
| Attach / access | One EC2 per volume (Multi-Attach exception) | HTTP/API; no attach | NFS mount; thousands of clients |
| Max size mindset | 64 TiB per volume (types vary) | Practically unlimited bucket | Petabyte-scale elastic |
| Latency | Low (microseconds–low ms to volume) | Higher (API round trip) | Low ms; not DB-class random I/O |
| AZ / Region | Single AZ per volume | Regional service; cross-Region replication optional | Regional (or One Zone) |
Durability, availability, and backup
| Dimension | EBS | S3 | EFS |
|---|---|---|---|
| Durability design | Replicated within AZ; 99.8–99.999% by volume type | 99.999999999% (11 nines) for objects across facilities | Regional: survives AZ loss; One Zone: AZ-scoped |
| Backup pattern | Snapshots → incremental in S3 backend | Versioning, replication, Glacier tiers | AWS Backup, replication to secondary Region |
| Disaster recovery | Copy snapshots AMIs cross-Region; rehearse restore time | CRR, Batch Replication, S3 Object Lock for compliance | EFS replication, failover runbooks |
Cost drivers (simplified)
| You pay for | EBS | S3 | EFS |
|---|---|---|---|
| Capacity | GiB-month provisioned (size of volume) | GiB-month per storage class | GiB-month (Standard vs IA tiers) |
| Performance | Provisioned IOPS & throughput (gp3, io) | Requests (PUT/GET/LIST); retrieval fees on IA/Glacier | Provisioned throughput if not using Elastic/Bursting |
| Data movement | Snapshot storage; cross-Region copy; no charge for attach in same AZ | Egress to internet; inter-Region replication | No charge for access from same AZ mount target; cross-AZ charges apply |
| Hidden waste | Unattached volumes, oversized gp2, old snapshots | Incomplete multipart uploads, non-current versions, wrong lifecycle | Over-provisioned throughput; cold data on Standard tier |
Decision flow (architect view)
Need POSIX files shared by many instances in real time?
└─ Yes → EFS (or FSx if you need Windows/SMB, Lustre, NetApp, etc.)
└─ No ↓
Need block device for OS or database on one (or clustered) instance?
└─ Yes → EBS (pick gp3 unless metrics prove io2)
└─ No ↓
Need durable objects, static assets, lake, backup target, event-driven processing?
└─ Yes → S3 (+ CloudFront, Lambda, Athena, lifecycle rules)
Workload cheat sheet
| Workload | Best fit | Why |
|---|---|---|
| EC2 root / boot volume | EBS (gp3) | Block device the hypervisor boots from |
| PostgreSQL / MySQL on EC2 | EBS io2/gp3 (or RDS, which uses EBS under the hood) | Predictable block I/O, snapshot backup story |
| Static website, images, videos | S3 + CloudFront | Massive scale, cheap $/GB, global edge |
| Data lake, ETL landing zone | S3 | Object semantics integrate with Glue, Athena, Spark |
| WordPress / shared HTML across Auto Scaling group | EFS | RWX without custom sync |
| Kubernetes stateful pod (single node writer) | EBS via CSI | RWO volumes; mind AZ topology |
| Kubernetes many-replica shared config | EFS via CSI | ReadWriteMany support |
| Long-term compliance archive | S3 Glacier Deep Archive | Lowest $/GB; retrieval hours acceptable |
Operations: commands and checks
EBS
# List volumes; note State and Attachment
aws ec2 describe-volumes --filters Name=attachment.instance-id,Values=i-0abc123
# Create gp3 volume (same AZ as instance!)
aws ec2 create-volume --availability-zone ap-south-1a --size 100 --volume-type gp3 \
--iops 3000 --throughput 125
# Snapshot
aws ec2 create-snapshot --volume-id vol-0abc --description "pre-upgrade-$(date +%F)"
# Find unattached volumes (FinOps)
aws ec2 describe-volumes --filters Name=status,Values=available
S3
# Sync directory (common deploy/backup pattern)
aws s3 sync ./build s3://my-app-assets-prod/ --delete
# Encryption default
aws s3api put-bucket-encryption --bucket my-bucket --server-side-encryption-configuration '{
"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "aws:kms"}}]}'
# Lifecycle example: transition to IA after 90 days
aws s3api put-bucket-lifecycle-configuration --bucket my-bucket --lifecycle-configuration file://lifecycle.json
EFS
# Create and mount (Amazon Linux 2/2023)
sudo mkdir /mnt/efs
sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 \
fs-abc123.efs.ap-south-1.amazonaws.com:/ /mnt/efs
# /etc/fstab for reboot persistence
fs-abc123.efs.ap-south-1.amazonaws.com:/ /mnt/efs nfs4 nfsvers=4.1,_netdev 0 0
Common mistakes
- EBS in the wrong AZ — Volume in
us-east-1a, instance inus-east-1b→ attach fails. Automate AZ in IaC. - Using S3 as a database disk — Wrong tool; use EBS, RDS, or DynamoDB depending on access pattern.
- EFS for high-IOPS random DB I/O — Latency and cost profile wrong; EBS or purpose-built DB service wins.
- Ignoring snapshot chain cost — Frequent snapshots of high-churn volumes add up; lifecycle old snapshots.
- Public S3 buckets — Still a headline breach vector; SCPs and Block Public Access at org level.
- Cross-AZ EFS traffic — Mount via mount target in the same AZ as the client when possible.
- Kubernetes zone skew — Pod rescheduled to another AZ while EBS volume is zonal → PVC Pending. Use topology-aware provisioning.
Beyond the triad (when none of the three is enough)
AWS storage does not end at EBS, S3, and EFS:
- Amazon FSx — Windows File Server (SMB), Lustre (HPC), NetApp ONTAP, OpenZFS—when protocol or performance requirements are specialized.
- AWS Backup — Centralized policies across EBS, EFS, RDS, DynamoDB, etc.
- Storage Gateway — Hybrid on-premises cache backed by S3.
- RDS / Aurora — Managed databases with their own storage subsystems (often EBS-based, but you operate at the DB layer).
The triad still covers most “where do I put bits?” questions at the architecture whiteboard.
Mental model checklist
- Classify the workload: block, object, or file.
- Map latency, IOPS, sharing, and durability requirements—not brand familiarity.
- For EBS: AZ + volume type + snapshot strategy.
- For S3: storage class + lifecycle + access policy + egress path.
- For EFS: throughput mode + mount target AZ alignment + tiering.
- Measure before upsizing; orphaned resources are a design smell and a carbon cost.
Further reading
- AWS — Amazon EBS User Guide (volume types, monitoring, CloudWatch metrics)
- AWS — Amazon S3 User Guide (storage classes, security, performance guidelines)
- AWS — Amazon EFS User Guide (performance modes, throughput, replication)
- AWS — AWS Well-Architected Framework — Reliability and Cost Optimization pillars
- AWS — EBS CSI driver and EFS CSI driver documentation for Kubernetes
Blog index · Amazon S3 in depth · Cloud Architecting · AWS network architecture · CRI vs CSI