Back to S3 & Storage
Q3Question 3 of 5

EBS, Volume Types, and Why gp3 Over gp2

Key Concepts
  • EBS is persistent, network-attached block storage for EC2 that survives instance stops and terminations.
  • gp3 is the preferred general-purpose SSD because it decouples IOPS and throughput from volume size and costs roughly twenty percent less than gp2.
  • gp2 ties performance to size at three IOPS per GiB, so small volumes are slow and you must over-provision capacity just to get speed.
  • io1 and io2 provisioned-IOPS SSDs deliver the highest consistent performance for latency-critical databases like the core banking ledger.
  • st1 and sc1 are HDD types optimized for large sequential throughput at low cost and cannot be used as boot volumes.
  • Migrating from gp2 to gp3 is done live with Elastic Volumes, with no downtime required.
  • gp3 provides a baseline of 3000 IOPS and 125 MB/s regardless of size, tunable up to 16000 IOPS and 1000 MB/s.

Definition

EBS is a persistent virtual disk for EC2, and gp3 beats gp2 because you tune IOPS and throughput separately from size and pay less.
  • EBS (Elastic Block Store) – a durable, network-attached block storage service for EC2 instances that behaves like a virtual hard disk and persists independently of the instance lifecycle.
  • gp2 and gp3 – general-purpose SSD volume types suitable for most workloads such as boot volumes and medium databases.
  • io1 and io2 – provisioned-IOPS SSD types for the highest, most consistent low-latency performance, used for critical transactional databases.
  • st1 (throughput-optimized) and sc1 (cold) – HDD types designed for large, sequential workloads at low cost; they cannot serve as boot volumes.
  • gp3 advantage – decouples IOPS and throughput from volume size and is roughly twenty percent cheaper per GiB than gp2.

Think of an EC2 server as a desk where a clerk at National Bank of India works, and EBS as the filing cabinet bolted next to the desk. The cabinet holds all the clerk's documents, and even if the clerk goes home (the instance stops), the cabinet and its documents stay. gp2 is an older cabinet where the speed of pulling out files depends on how big the cabinet is – a small cabinet is slow. gp3 is a newer cabinet where you can dial the speed up or down separately from the size, and it costs less, so you pay only for the speed you actually need.

Understanding the Concepts

What is EBS?

EBS (Elastic Block Store) provides durable, network-attached block storage volumes for EC2 instances. The operating system formats it with a filesystem and uses it like a local disk, but the storage lives separately from the physical host and is replicated within an Availability Zone for durability. The key property is persistence: if an instance is stopped or even terminated (when the volume is not set to delete on termination), the EBS volume and its data survive and can be re-attached to another instance.

JAVA
// Conceptual model of an EBS volume attachment
package com.bank.infrastructure;

public class EbsVolume {
    private final String volumeId;
    private final String volumeType;  // gp3, gp2, io2, io1, st1, sc1
    private final int sizeGiB;
    private final String availabilityZone;
    private boolean attached;

    public EbsVolume(String volumeId, String volumeType, int sizeGiB, String az) {
        this.volumeId = volumeId;
        this.volumeType = volumeType;
        this.sizeGiB = sizeGiB;
        this.availabilityZone = az;
        this.attached = false;
    }

    public void attachTo(String instanceId) {
        // Volume persists even when detached
        this.attached = true;
        System.out.println("Volume " + volumeId + " attached to " + instanceId);
    }
}

Why does EBS exist and why do we need different volume types?

EC2 instance store (ephemeral storage) is lost when an instance stops, which is unacceptable for persistent data like a banking database or application logs. EBS gives you durable storage that survives instance lifecycle events. Different volume types exist because workloads have different performance and cost profiles. A boot volume for an internal tool has different needs than the core banking ledger, and paying io2 prices for a log volume would waste money.

JAVA
// Matching volume type to workload
package com.bank.infrastructure;

import java.util.Map;

public class VolumeSelector {
    private static final Map<String, String> WORKLOAD_TO_TYPE = Map.of(
        "boot-volume",       "gp3",
        "medium-database",   "gp3",
        "core-ledger-db",    "io2",
        "log-archive",       "st1",
        "cold-compliance",   "sc1"
    );

    public static String recommend(String workload) {
        return WORKLOAD_TO_TYPE.getOrDefault(workload, "gp3");
    }
}

How does gp3 differ from gp2?

With gp2, performance is tied to volume size: you get three IOPS per gigabyte, with a minimum burst of 3000 IOPS for small volumes via a burst credit mechanism. A 100 GiB gp2 volume delivers only 300 baseline IOPS, so you must over-provision size just to get speed. With gp3, you get a flat baseline of 3000 IOPS and 125 MB/s of throughput regardless of size, and you can independently provision up to 16000 IOPS and 1000 MB/s. On top of this, gp3 is roughly twenty percent cheaper per GiB.

| Feature | gp2 | gp3 |
|---|---|---|
| Baseline IOPS | 3 per GiB (min 100) | 3000 flat |
| Max IOPS | 16000 (at 5334+ GiB) | 16000 (independently) |
| Baseline throughput | Tied to IOPS | 125 MB/s flat |
| Max throughput | 250 MB/s | 1000 MB/s |
| Cost per GiB | Higher | ~20% cheaper |

JAVA
// Illustrating the gp2 vs gp3 difference as a simple calculation
package com.bank.infrastructure;

public class VolumePerformanceComparison {
    public static void main(String[] args) {
        int sizeGiB = 100;

        // gp2: locked to 3 IOPS per GiB
        int gp2Iops = sizeGiB * 3; // 300 IOPS for 100 GiB
        System.out.println("gp2 100 GiB baseline IOPS: " + gp2Iops);

        // gp3: 3000 baseline regardless of size
        int gp3BaselineIops = 3000;
        int gp3ProvisionedIops = 6000; // can raise independently
        System.out.println("gp3 100 GiB baseline IOPS: " + gp3BaselineIops);
        System.out.println("gp3 100 GiB provisioned IOPS: " + gp3ProvisionedIops);
    }
}
TEXT
gp2 100 GiB baseline IOPS: 300
gp3 100 GiB baseline IOPS: 3000
gp3 100 GiB provisioned IOPS: 6000

What are provisioned-IOPS SSD types (io1 and io2)?

These are for workloads that need the highest and most predictable performance, such as the core banking ledger at National Bank of India. io2 improves on io1 with higher durability (99.999% vs 99.9%) and a better IOPS-to-size ratio (500 IOPS per GiB vs 50). io2 Block Express can reach up to 256000 IOPS and 4000 MB/s. You pay a premium, so these are reserved for cases where consistent sub-millisecond latency is critical.

JAVA
// When provisioned-IOPS is the right choice
package com.bank.infrastructure;

public class ProvisionedIopsDecision {
    public static String evaluateVolumeType(int requiredIops, boolean needsSubMsLatency) {
        if (requiredIops > 16000 || needsSubMsLatency) {
            return "io2"; // exceeds gp3 ceiling or needs guaranteed low latency
        }
        return "gp3"; // gp3 handles up to 16000 IOPS at lower cost
    }
}

What are HDD volume types (st1 and sc1)?

The HDD types are magnetic and optimized for large, sequential throughput rather than small random reads. st1 (throughput-optimized) delivers up to 500 MB/s for big streaming workloads like log processing, batch data warehousing, or Kafka brokers. sc1 (cold HDD) is the cheapest option for data you rarely access. Neither can be used as a boot volume.

JAVA
// Selecting HDD for sequential workloads
package com.bank.infrastructure;

public class HddVolumeSelector {
    public static String selectHddType(String accessPattern) {
        return switch (accessPattern) {
            case "frequent-sequential" -> "st1"; // log processing, ETL
            case "rare-sequential"     -> "sc1"; // cold audit archive
            default -> throw new IllegalArgumentException("HDD not suitable for: " + accessPattern);
        };
    }
}

How do you migrate from gp2 to gp3?

Migration is done live with the Elastic Volumes feature. You modify the volume type through the console, CLI, or API, and the change happens in the background with no downtime and no detach required. The volume enters an "optimizing" state during the transition. At National Bank of India, the reporting service ran a 100 GiB gp2 data volume that gave only 300 IOPS, and the team considered inflating it to a terabyte just to get speed. Instead, migrating to gp3 gave a 3000 IOPS baseline on the same 100 GiB and allowed provisioning up to 6000 IOPS without buying unused space.

BASH
# Live migration from gp2 to gp3 with no downtime
aws ec2 modify-volume --volume-id vol-0abc123 --volume-type gp3 --iops 6000 --throughput 250

What are the rules and constraints?

EBS volumes are tied to a single Availability Zone and cannot be attached across zones. To move a volume to another zone, you create a snapshot and restore it in the target zone. A volume can be attached to only one instance at a time (except io1/io2 with Multi-Attach). Snapshots are incremental and stored in S3. gp3 IOPS can be provisioned only up to a ratio of 500 IOPS per GiB of volume size.

JAVA
// Validating IOPS provisioning constraint
package com.bank.infrastructure;

public class IopsValidator {
    private static final int MAX_IOPS_PER_GIB = 500;
    private static final int GP3_MAX_IOPS = 16000;

    public static int validateIops(int sizeGiB, int requestedIops) {
        int maxAllowed = Math.min(sizeGiB * MAX_IOPS_PER_GIB, GP3_MAX_IOPS);
        if (requestedIops > maxAllowed) {
            throw new IllegalArgumentException(
                "Requested " + requestedIops + " IOPS exceeds max " + maxAllowed
                + " for " + sizeGiB + " GiB volume");
        }
        return requestedIops;
    }
}

What about performance tuning and monitoring?

Use CloudWatch metrics to monitor EBS performance: VolumeReadOps, VolumeWriteOps, VolumeQueueLength, and BurstBalance (for gp2). A high queue length indicates the volume is a bottleneck. For gp2, watch BurstBalance dropping to zero, which means the volume has exhausted its burst credits and is throttled to baseline. This is one of the strongest reasons to switch to gp3, where there is no burst credit mechanism and the baseline is always 3000 IOPS.

JAVA
// Monitoring EBS performance with CloudWatch
package com.bank.monitoring;

import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
import software.amazon.awssdk.services.cloudwatch.model.*;
import java.time.Instant;
import java.util.List;

public class EbsMonitor {
    private final CloudWatchClient cw = CloudWatchClient.create();

    public double getAverageQueueLength(String volumeId) {
        GetMetricStatisticsResponse resp = cw.getMetricStatistics(
            GetMetricStatisticsRequest.builder()
                .namespace("AWS/EBS")
                .metricName("VolumeQueueLength")
                .dimensions(Dimension.builder().name("VolumeId").value(volumeId).build())
                .startTime(Instant.now().minusSeconds(3600))
                .endTime(Instant.now())
                .period(300)
                .statistics(Statistic.AVERAGE)
                .build());
        return resp.datapoints().stream()
            .mapToDouble(Datapoint::average).average().orElse(0.0);
    }
}

When should you use each volume type?

  • gp3 – the default for most workloads: boot volumes, application data, medium databases, development environments.
  • io2 – core banking databases, Oracle RAC, any workload needing more than 16000 IOPS or guaranteed sub-millisecond latency.
  • st1 – Kafka brokers, Hadoop HDFS, log aggregation, ETL data staging.
  • sc1 – cold compliance archives, infrequently accessed backups.
  • gp2 – legacy only; migrate to gp3 for better performance at lower cost.
JAVA
// Decision matrix for volume type selection
package com.bank.infrastructure;

public class VolumeTypeAdvisor {
    public static String advise(int requiredIops, boolean sequential, boolean cold) {
        if (cold) return "sc1";
        if (sequential) return "st1";
        if (requiredIops > 16000) return "io2";
        return "gp3";
    }
}

Visual Overview

DIAGRAM
                        EBS Volume Types Decision Tree

  ┌─────────────────────────────────────────────────────────────────┐
  │                     What is the access pattern?                │
  └──────────────────────────┬──────────────────────────────────────┘
                             │
              ┌──────────────┴──────────────┐
              ▼                             ▼
       Random (SSD)                  Sequential (HDD)
              │                             │
     ┌────────┴────────┐           ┌────────┴────────┐
     ▼                 ▼           ▼                 ▼
  ≤16K IOPS       >16K IOPS    Frequent           Rare
     │                 │           │                 │
     ▼                 ▼           ▼                 ▼
  ┌──────┐       ┌──────┐     ┌──────┐         ┌──────┐
  │ gp3  │       │ io2  │     │ st1  │         │ sc1  │
  │      │       │      │     │      │         │      │
  │3000  │       │Up to │     │500   │         │250   │
  │IOPS  │       │256K  │     │MB/s  │         │MB/s  │
  │base  │       │IOPS  │     │      │         │      │
  └──────┘       └──────┘     └──────┘         └──────┘


                  gp2 vs gp3 Performance Model

  gp2 (size-coupled):     gp3 (decoupled):
  ┌─────────────────┐     ┌─────────────────────┐
  │ Size: 100 GiB   │     │ Size: 100 GiB       │
  │ IOPS: 300       │     │ IOPS: 3000 (base)   │
  │ (3 x 100)       │     │ Can tune to 16000   │
  │ Throughput: tied │     │ Throughput: 125 MB/s│
  │ to IOPS         │     │ Can tune to 1000    │
  │ Cost: $$$       │     │ Cost: $$            │
  └─────────────────┘     └─────────────────────┘
  To get more IOPS,       IOPS and throughput are
  you MUST buy more       independent dials you
  size (wasteful).        turn without buying size.

Key Takeaway

Amazon Elastic Block Store, or EBS, is durable network-attached block storage for EC2 instances. It behaves like a virtual hard disk that the operating system formats and uses like a local drive, but it is replicated within an Availability Zone for durability and persists independently of the instance. If I stop or terminate the instance, the volume and its data survive and can be re-attached elsewhere.

There are four families of volume types. The general-purpose SSDs, gp2 and gp3, cover most workloads like boot volumes and medium databases. The provisioned-IOPS SSDs, io1 and io2, deliver the highest and most consistent performance for latency-critical workloads like the core banking ledger. The HDDs, st1 and sc1, are magnetic and tuned for large sequential throughput at low cost, suited to log processing and cold data, and they cannot be boot volumes.

The reason gp3 is almost always preferred over gp2 is that gp2 ties performance to size at three IOPS per gigabyte, so a small volume is slow and you end up over-provisioning capacity just to buy speed. gp3 decouples performance from size entirely: it gives a flat 3000 IOPS and 125 MB/s baseline regardless of volume size, and I can raise IOPS and throughput independently up to 16000 IOPS and 1000 MB/s. On top of this, gp3 is roughly twenty percent cheaper per gigabyte, and I can migrate from gp2 to gp3 live using Elastic Volumes with no downtime.

At National Bank of India, the reporting service ran a 100 GiB gp2 data volume that gave only 300 baseline IOPS, and the team wanted to inflate it to a terabyte just to get speed. I moved it to gp3, which gave a 3000 IOPS baseline on the same 100 GiB and let me provision up to 6000 IOPS without buying unused space, cutting cost at the same time. The one place I kept provisioned-IOPS io2 was the core ledger database, because it needs more than 16000 IOPS and demands rock-solid consistent low latency.

Remember one sentence: gp3 decouples IOPS and throughput from volume size, gives a 3000 IOPS baseline regardless of capacity, and costs about twenty percent less than gp2, making it the default EBS choice for almost every workload.

---

Share
Use ← → arrow keys to navigate