The most surprising thing about EBS volume types is that gp3 is almost always the right choice for most workloads, despite the existence of supposedly "higher performance" options.

Let’s see gp3 in action. Imagine you’re spinning up a new EC2 instance for a web server. You need storage for the OS and your application files. You could pick io1 or io2, which are provisioned IOPS volumes, or st1, which is designed for throughput-intensive workloads. But gp3 offers a baseline performance that’s often more than enough, and it’s significantly cheaper.

Here’s a typical scenario: you’re launching an m5.large instance and need a 100GiB root volume.

aws ec2 create-volume --availability-zone us-east-1a --size 100 --volume-type gp3 --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=my-webserver-root}]'

This command creates a 100GiB gp3 volume. What’s remarkable is that gp3 volumes come with a default baseline performance of 3,000 IOPS and 125 MiB/s throughput regardless of the volume size. You don’t pay extra for this baseline. If your web server’s disk activity stays within these limits, you’re getting great performance for free.

The problem gp3 solves is the complexity and cost of older EBS types. Before gp3, if you needed more than the baseline performance of gp2 (which scaled IOPS with size), you’d have to jump to io1/io2 (expensive provisioned IOPS) or st1 (good for sequential throughput, bad for random access). gp3 bridges this gap by allowing you to provision IOPS and throughput independently of size, at a much lower cost than io1/io2.

Internally, gp3 volumes are built on solid-state drives (SSDs). The key difference from gp2 is the decoupling of performance metrics from storage capacity. With gp2, you got 3 IOPS per GiB of storage, capped at 16,000 IOPS. If you needed 5,000 IOPS for a 100GiB volume, you’d have to provision 1667 GiB of gp2 storage (5000 / 3), which is massive overkill and expensive. With gp3, you provision 100GiB of storage, and then separately configure 5,000 IOPS and, say, 200 MiB/s throughput.

aws ec2 create-volume --availability-zone us-east-1a --size 100 --volume-type gp3 --iops 5000 --throughput 200 --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=my-webserver-root}]'

You control the performance by adjusting the --iops and --throughput parameters. The maximums for gp3 are 16,000 IOPS and 1,000 MiB/s.

For workloads that are truly throughput-intensive and involve large, sequential reads/writes (like log processing or data warehousing with sequential scans), st1 might still be considered. It offers up to 500 MiB/s throughput per volume (up to 250 MiB/s for sc1, the lowest tier) at a lower cost than gp3, but its IOPS performance is significantly lower and can be inconsistent. io2 is for mission-critical, I/O-intensive transactional workloads that demand the absolute lowest latency and highest IOPS, with durability guarantees that gp3 doesn’t match.

The one thing most people don’t realize about gp3’s pricing is that you pay for storage capacity, IOPS, and throughput separately, and the cost per provisioned IOPS and per provisioned MiB/s is substantially lower than the equivalent provisioned IOPS on io1/io2. This allows for fine-grained performance tuning without the massive cost penalty of over-provisioning storage just to get more IOPS.

The next step is understanding how to monitor EBS volume performance to know when to adjust your gp3 settings.

Want structured learning?

Take the full Ec2 course →