Select by IOPS and throughput
gp3 is the common general-purpose SSD choice and lets you configure IOPS and throughput independently of size (baseline 3,000 IOPS and 125 MiB/s). io2 Block Express fits workloads needing very high IOPS and consistent latency; st1 fits sequential throughput; sc1 fits cold HDD data. st1 and sc1 cannot be boot volumes.
flowchart LR
B{"Boot volume?"} -- "yes" --> S["gp3<br/>or io2"]
B -- "no" --> L{"Latency-critical<br/>database?"}
L -- "yes" --> IO["io2 Block Express<br/>high IOPS"]
L -- "no" --> W{"Large sequential<br/>reads?"}
W -- "frequent" --> T["st1<br/>throughput HDD"]
W -- "cold" --> C["sc1<br/>cold HDD"]
%% step B: Boot volumes must be SSD: gp2, gp3, io1 or io2.
%% step S: gp3 is the default for most boot and app volumes.
%% step L: Databases that need many small, fast operations care about IOPS and latency.
%% step IO: io2 gives provisioned IOPS with the most consistent latency and highest durability.
%% step W: Big streaming workloads such as logs or data processing care about MiB/s.
%% step T: st1 is cheap per GB for frequently read sequential data.
%% step C: sc1 is cheapest, for data read rarely.
Volume types
| Type | Media | Bootable | Strength |
|---|---|---|---|
| gp3 | SSD | Yes | Set IOPS and throughput separately from size; cheaper than gp2 |
| gp2 | SSD | Yes | Older: IOPS grow with size (3 IOPS per GiB), burst credits on small volumes |
| io2 Block Express | SSD | Yes | Highest IOPS and durability, sub-millisecond latency |
| st1 | HDD | No | Throughput for big sequential data |
| sc1 | HDD | No | Lowest cost, cold data |
You can change type, size and performance of a live volume with Elastic Volumes, for example gp2 → gp3, usually with no downtime. Instance limits still apply: a small instance type caps total EBS bandwidth, so a fast volume on a tiny instance cannot reach its rating.
Multi-Attach
Multi-Attach is available only for io1/io2 volumes, and instances must be in one AZ. Every node has read/write access, so the filesystem or application must coordinate concurrent writes; ordinary ext4 or XFS will corrupt data. It is for clustered software built for shared disks.
Encryption
EBS encryption uses KMS (the AWS managed key aws/ebs or your own customer managed key) and protects data at rest, snapshots, and instance-to-volume traffic, with no measurable performance cost on modern instances. Snapshots of encrypted volumes are encrypted, and volumes made from them too.
You cannot directly switch encryption on for an old volume: snapshot it, create an encrypted snapshot copy, and build a new volume. Better: turn on EBS encryption by default for the Region so every new volume is encrypted automatically. To share an encrypted snapshot with another account you must use a customer managed key and share the key too.
RAID
RAID 0 increases throughput but loses the array if one volume fails; RAID 1 mirrors data but adds cost and traffic. EBS already replicates each volume within its AZ, so RAID 1 is rarely needed, and modern gp3/io2 limits often make RAID 0 unnecessary.
| Command | Purpose |
|---|---|
aws ec2 create-volume --volume-type gp3 --size 100 --iops 6000 --throughput 250 --availability-zone ap-southeast-1a |
Create a gp3 volume with extra performance |
aws ec2 modify-volume --volume-id vol-0a1b2c3d --volume-type gp3 |
Change type in place |
aws ec2 copy-snapshot --encrypted --kms-key-id alias/ebs-key ... |
Create an encrypted snapshot copy |
aws ec2 enable-ebs-encryption-by-default |
Encrypt new volumes in this Region |
Traps: choosing st1 for a boot volume; using Multi-Attach with a normal filesystem; looking for an "encrypt" button on an existing volume.