Amazon EBS performance depends on the volume, the EC2 instance that carries its I/O, and the guest operating system and application. A volume can be below its limit while the instance is saturated, or provisioned for more work than the application sends. Diagnose the constrained layer before changing volume type, IOPS, or throughput.

This guide covers ten common causes and shows how to distinguish them using CloudWatch and Linux signals. For a repeatable method to compare storage changes against a representative workload, see our HPC workload profiling guide.

Start with measurements at the right layer

Amazon EBS publishes per-volume metrics in the AWS/EBS namespace, identified by the VolumeId dimension. The standard metrics arrive in one-minute periods while the volume is attached to an instance. In CloudWatch, use the Sum statistic for operation and byte counts, then divide by the period in seconds to get a rate:

  • Average IOPS: (VolumeReadOps Sum + VolumeWriteOps Sum) ÷ period seconds.
  • Average throughput: (VolumeReadBytes Sum + VolumeWriteBytes Sum) ÷ period seconds ÷ 1,048,576 for MiB/s.

Compare those rates with the volume's configured IOPS and throughput. Add VolumeQueueLength and read/write latency to see whether requests are waiting. One-minute averages can hide short bursts; where supported, the VolumeIOPSExceededCheck and VolumeThroughputExceededCheck metrics indicate whether the workload consistently attempted to exceed the volume's configured IOPS or throughput during the previous minute. VolumeStalledIOCheck reports whether the volume can complete I/O. Check each metric's exact namespace, dimensions, period, and available statistics before interpreting it.

Do not use EC2's DiskReadOps or DiskWriteOps as EBS metrics: those report instance-store activity. Supported Nitro instances also publish EC2-level EBS metrics, which help reveal an instance-wide limit. Our EC2 CloudWatch monitoring guide explains these metric scopes and periods. The official EBS CloudWatch metrics reference lists availability, units, dimensions, and statistics.

Replace the example volume ID with one from your account. These read-only commands show volume configuration and guest-device activity; they do not write to a volume:

aws ec2 describe-volumes --volume-ids vol-0123456789abcdef0 --query 'Volumes[].{Volume:VolumeId,Type:VolumeType,SizeGiB:Size,IOPS:Iops,ThroughputMiBs:Throughput,State:State}' --output table
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
iostat -xz 1

Install the Linux sysstat package if iostat is unavailable. On Nitro instances, EBS devices usually appear as NVMe devices in the guest, so device names may differ from the names used when attaching a volume.

1. The volume's IOPS limit is too low

If workload demand reaches the volume's provisioned IOPS while latency or queue length rises, the volume may be IOPS-bound. Confirm the volume type and configured performance before increasing capacity. General Purpose SSD gp3 includes 3,000 IOPS and 125 MiB/s; in standard AWS Regions it can be provisioned up to 80,000 IOPS and 2,000 MiB/s, subject to volume-size and IOPS-to-size ratios. Provisioned IOPS SSD io2 Block Express volumes can reach 256,000 IOPS on Nitro-based instances and 4,000 MiB/s, but volume-size ratios and the instance's aggregate limit still apply. See AWS's current gp3 limits and io2 Block Express limits; Outposts has different gp3 limits.

Increase provisioned IOPS only when the application needs more operations and the instance has enough EBS capacity to deliver them. Otherwise, changing from gp3 to io2 can increase cost without removing the actual bottleneck. For a database or latency-sensitive service, include its latency objective and the workload's read/write pattern in the choice.

2. Throughput is capped before IOPS are exhausted

A volume can hit its throughput limit even when its IOPS graph is below the provisioned value. For a rough estimate, throughput in MiB/s is IOPS × I/O size in KiB ÷ 1,024. At 3,000 IOPS, 16 KiB requests represent about 47 MiB/s; 256 KiB requests represent about 750 MiB/s. A gp3 volume left at its 125 MiB/s baseline throughput would therefore reach its throughput ceiling well before 3,000 requests per second at 256 KiB each.

Compare read and write bytes per second with the volume's throughput setting and with the EC2 instance's EBS limit. If large sequential requests dominate, raising IOPS alone may not help. Increase the volume's throughput when that is the constrained limit, or reduce avoidable data transfer if the application can do so. AWS explains the relationship in its EBS I/O and throughput guidance.

3. The EC2 instance's aggregate EBS limit is reached

Each attached volume shares the EBS connection available to its EC2 instance. Actual performance is bounded by the smaller of the volume's performance and the instance's aggregate EBS limit. Compare the exact instance type's baseline and maximum EBS bandwidth and IOPS with the combined demand of all attached volumes. An instance being EBS-optimized does not mean it can deliver every attached volume's maximum performance at once.

On supported instance types, EBS and VPC network bandwidth can also share configurable bandwidth allocations. A setting that raises EBS bandwidth can reduce VPC networking bandwidth, so measure both sides after changing it. Check the current EBS-optimized instance guidance and the exact instance specifications. Our EC2 right-sizing guide covers how to compare storage, network, and other instance limits against workload history.

4. I/O size and request counting do not match expectations

The application's I/O calls, guest block-device requests, and operations counted by EBS are not always one-to-one. EBS counts up to 256 KiB as one I/O for SSD volumes and up to 1,024 KiB for HDD volumes. It can split larger requests and attempt to merge physically sequential smaller requests. For example, one 1,024 KiB request becomes four 256 KiB operations for an SSD volume; eight sequential 32 KiB requests can be counted as one 256 KiB operation, while eight random 32 KiB requests remain eight operations.

The guest operating system can also merge requests before sending them to EBS, so IOPS measured inside Linux can differ from EBS volume metrics. Compare measurements from the same layer and time period, and use the published EBS metrics when checking provisioned volume performance.

5. The workload does not send enough concurrent I/O

Provisioned performance is a ceiling, not a target EBS can reach without enough work in flight. An application that issues one synchronous request and waits for completion may leave IOPS unused even when the volume is configured for more. If utilization is low and latency is acceptable, adding IOPS will not make a serialized workload faster.

Check application and database concurrency alongside VolumeQueueLength, IOPS, throughput, and latency. Raise concurrency only if the application supports it and the added outstanding I/O does not violate its latency objective. Queue depth that works for one request size and application can be too low or too high for another; AWS's queue-length guidance describes the relationship among queueing, I/O size, and latency.

6. A volume created from a snapshot is still initializing

When a volume is restored from a snapshot, blocks that have not yet been downloaded and written can have higher first-access latency. Full performance is available after initialization completes. Check the volume's initialization state before attributing first-read delays to the application's storage configuration.

Current options include Fast Snapshot Restore, which creates a fully initialized volume when enabled for the snapshot and Availability Zone. Its full performance benefit applies up to 64,000 IOPS and 1,000 MiB/s; for a volume provisioned above either limit, AWS recommends additional initialization. Another option is an EBS Provisioned Rate for Volume Initialization between 100 and 300 MiB/s. Both options add charges: FSR while it is enabled, and the provisioned rate based on snapshot data and the selected rate. You can also manually read all blocks from a restored volume; that consumes instance and volume resources, so schedule it with the workload and recovery plan in mind. Empty volumes are immediately ready and do not need initialization. See AWS's current volume initialization options.

7. Burst credits have run out

Some older or HDD volume types can burst above baseline performance only while credits remain. gp2 volumes below 1 TiB can burst to 3,000 IOPS when their baseline is lower; st1 and sc1 use throughput credits. After the credit balance is depleted, performance returns to baseline. Check the CloudWatch BurstBalance metric for these types. gp3 does not use burst performance and can sustain its provisioned IOPS and throughput.

If sustained load repeatedly exhausts credits, size for the workload's baseline or consider a volume type with provisioned performance. Check both cost and expected traffic before migrating; a short boot or startup burst is different from steady-state demand. AWS documents the current credit behavior for gp2 and st1 and sc1.

8. Small, random I/O is using a throughput HDD volume

Throughput Optimized HDD (st1) and Cold HDD (sc1) are designed for large, sequential I/O. Small random reads or writes can use their I/O capacity inefficiently and deliver lower throughput than expected. They are a poor fit for many transactional databases and latency-sensitive random workloads; consider SSD-backed gp3 or io2 based on the required performance.

For an HDD workload, compare average I/O size with the transfer pattern and check BurstBalance, volume throughput, and instance EBS throughput together. Large sequential data processing, such as log or batch workloads, is a better fit. Do not stripe volumes or change application I/O size without checking how that affects failure recovery and data layout.

9. Guest operating-system settings limit the I/O path

The filesystem, block layer, device driver, CPU, and application can limit I/O before it reaches EBS. Use iostat -xz 1, application latency, CPU and I/O-wait data, and kernel logs to identify the busy part of the guest path. Device names and available scheduler settings vary by operating system and instance generation. A scheduler such as noop is not a universal recommendation, and changing the kernel or block-device settings should follow a measured symptom.

Read-ahead is workload-specific too. AWS recommends a 1 MiB read-ahead setting only for certain Linux, read-heavy st1 or sc1 workloads that read through the operating-system page cache. That advice does not apply automatically to SSD volumes or direct I/O. See the scoped EBS performance tips and test any guest-level change against the real application.

10. One volume is hot while others are idle

An EC2 instance can have EBS headroom while a single volume reaches its IOPS or throughput limit. Compare metrics by VolumeId instead of relying only on an instance-wide total. A database file, log, or data partition may concentrate most requests on one volume even when other attached volumes are quiet.

Increase that volume's IOPS or throughput if the workload requires it and the instance has capacity. A compatible application or storage layout may distribute work across multiple volumes, but adding volumes does not bypass the instance-wide EBS limit. Striping can also make recovery depend on every member volume, so include backup and restore behavior in the design.

A practical EBS diagnosis sequence

  1. Record the application's latency, throughput, and read/write pattern for a representative period.
  2. Inspect each volume's type, provisioned IOPS, throughput, initialization status, and per-volume CloudWatch metrics.
  3. Compare EBS demand with the attached instance's aggregate EBS limits and other network use.
  4. Use queue depth, latency, burst balance, health checks, and guest-device data to distinguish a limit from a workload that is not issuing enough I/O.
  5. Change one constraint at a time, then compare application results and cost with the baseline.

Amazon EBS limits are only one part of application performance. A capacity change helps when evidence points to that exact limit; it cannot correct serialized application I/O, a saturated instance, or an initializing snapshot on its own.