[アップデート] EBSボリュームで1分間の平均IOPSとスループットを表すCloudWatchメトリクスが追加されました
自分でEBSボリュームのIOPSやスループットを計算するの面倒だな
こんにちは、のんピ(@non____97)です。
皆さんは自分でEBSボリュームのIOPSやスループットを計算するの面倒だなと思ったことはありますか? 私はあります。
「EC2コンソールからIOPSはないものの、以下のように読み取りスループットや書き込みスループットは見れるじゃないの」と思われる方もいるかもしれません。

しかし、こちらの読み取りスループットのウィジェットをメトリクスで開くと、以下のように読み取りデータ量を統計期間で割っていることが分かります。(1,024は単位をKiBにするための調整)

要するに直接的にスループットを表すメトリクスが存在している訳ではありませんでした。
CloudWatchのコンソールから手早くスループットやIOPSを把握したいときに、このように計算をするのは地味に面倒です。
そんな折、EBSボリュームで1分間の平均IOPSとスループットを表すCloudWatchメトリクスが追加されました。
具体的なメトリクスはAWS公式ドキュメントで紹介されている以下です。
- VolumeAvgIOPS
- VolumeAvgThroughput
これにより簡単にIOPSやスループットを確認できるようになりました。
実際に確認をしてみます。
やってみた
検証環境
検証は以下のEC2インスタンス、EBSボリュームを用いて行います。
- AZ : us-east-1d (use1-az4)
- AMI : al2023-ami-2023.9.20251020.0-kernel-6.1-x86_64 (ami-07860a2d7eb515d9a)
- インスタンスタイプ : t3.micro
- EBSボリュームタイプ : gp3
- EBSボリュームスループット : 125 MBps
- EBSボリュームIOPS : 3,000 IOPS

追加で用意したボリュームにfioで書き込みます。
追加したボリュームは以下のようにxfsでフォーマットしてマウントします。
$ sudo lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
nvme0n1
├─nvme0n1p1 xfs / 4a77b7a2-6d11-4714-ba76-e7dc21d23cc9 6.3G 21% /
├─nvme0n1p127
└─nvme0n1p128 vfat FAT16 161A-5EA2 8.7M 13% /boot/efi
nvme1n1
$ sudo mkfs -t xfs /dev/nvme1n1
meta-data=/dev/nvme1n1 isize=512 agcount=8, agsize=262144 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=1 bigtime=1 inobtcount=1 nrext64=0
= exchange=0
data = bsize=4096 blocks=2097152, imaxpct=25
= sunit=1 swidth=1 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1, parent=0
log =internal log bsize=4096 blocks=16384, version=2
= sectsz=512 sunit=1 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
$ sudo lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
nvme0n1
├─nvme0n1p1 xfs / 4a77b7a2-6d11-4714-ba76-e7dc21d23cc9 6.3G 21% /
├─nvme0n1p127
└─nvme0n1p128 vfat FAT16 161A-5EA2 8.7M 13% /boot/efi
nvme1n1 xfs f01da118-d2cc-465c-8b49-13ed3c5fcf72
$ sudo mkdir -p /mnt/vol
$ sudo mount /dev/nvme1n1 /mnt/vol/
$ df -hT
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 4.0M 0 4.0M 0% /dev
tmpfs tmpfs 453M 0 453M 0% /dev/shm
tmpfs tmpfs 181M 432K 181M 1% /run
/dev/nvme0n1p1 xfs 8.0G 1.7G 6.3G 21% /
tmpfs tmpfs 453M 0 453M 0% /tmp
/dev/nvme0n1p128 vfat 10M 1.3M 8.7M 13% /boot/efi
tmpfs tmpfs 91M 0 91M 0% /run/user/0
/dev/nvme1n1 xfs 8.0G 90M 7.9G 2% /mnt/vol
5分間書き込みをしてみる
実際にfioで書き込みをします。5分間書き込みをします。
$ sudo fio \
--directory=/mnt/vol/ \
--name fio_rw_1MiB_block_1GiB_4jobs \
--ioengine=psync \
--direct=1 \
--rw=randwrite \
--bs=1M \
--size=1G \
--numjobs=4 \
--runtime=300 \
--eta-newline=10 \
--time_based=1 \
--group_reporting \
--norandommap
fio_rw_1MiB_block_1GiB_4jobs: (g=0): rw=randwrite, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=psync, iodepth=1
...
fio-3.32
Starting 4 processes
fio_rw_1MiB_block_1GiB_4jobs: Laying out IO file (1 file / 1024MiB)
fio_rw_1MiB_block_1GiB_4jobs: Laying out IO file (1 file / 1024MiB)
fio_rw_1MiB_block_1GiB_4jobs: Laying out IO file (1 file / 1024MiB)
fio_rw_1MiB_block_1GiB_4jobs: Laying out IO file (1 file / 1024MiB)
Jobs: 4 (f=4): [w(4)][4.0%][w=125MiB/s][w=125 IOPS][eta 04m:48s]
Jobs: 4 (f=4): [w(4)][7.7%][w=125MiB/s][w=125 IOPS][eta 04m:37s]
Jobs: 4 (f=4): [w(4)][11.3%][w=125MiB/s][w=125 IOPS][eta 04m:26s]
Jobs: 4 (f=4): [w(4)][15.0%][w=125MiB/s][w=125 IOPS][eta 04m:15s]
Jobs: 4 (f=4): [w(4)][18.7%][w=126MiB/s][w=126 IOPS][eta 04m:04s]
Jobs: 4 (f=4): [w(4)][22.3%][w=125MiB/s][w=125 IOPS][eta 03m:53s]
Jobs: 4 (f=4): [w(4)][26.0%][w=125MiB/s][w=125 IOPS][eta 03m:42s]
Jobs: 4 (f=4): [w(4)][29.7%][w=125MiB/s][w=125 IOPS][eta 03m:31s]
Jobs: 4 (f=4): [w(4)][33.3%][w=92.1MiB/s][w=92 IOPS][eta 03m:20s]
Jobs: 4 (f=4): [w(4)][37.0%][w=126MiB/s][w=126 IOPS][eta 03m:09s]
Jobs: 4 (f=4): [w(4)][40.7%][w=122MiB/s][w=122 IOPS][eta 02m:58s]
Jobs: 4 (f=4): [w(4)][44.3%][w=125MiB/s][w=125 IOPS][eta 02m:47s]
Jobs: 4 (f=4): [w(4)][48.0%][w=125MiB/s][w=125 IOPS][eta 02m:36s]
Jobs: 4 (f=4): [w(4)][51.7%][w=117MiB/s][w=117 IOPS][eta 02m:25s]
Jobs: 4 (f=4): [w(4)][55.3%][w=126MiB/s][w=126 IOPS][eta 02m:14s]
Jobs: 4 (f=4): [w(4)][59.0%][w=126MiB/s][w=126 IOPS][eta 02m:03s]
Jobs: 4 (f=4): [w(4)][62.7%][w=125MiB/s][w=125 IOPS][eta 01m:52s]
Jobs: 4 (f=4): [w(4)][66.3%][w=125MiB/s][w=125 IOPS][eta 01m:41s]
Jobs: 4 (f=4): [w(4)][70.0%][w=125MiB/s][w=125 IOPS][eta 01m:30s]
Jobs: 4 (f=4): [w(4)][73.7%][w=125MiB/s][w=125 IOPS][eta 01m:19s]
Jobs: 4 (f=4): [w(4)][77.3%][w=125MiB/s][w=125 IOPS][eta 01m:08s]
Jobs: 4 (f=4): [w(4)][81.0%][w=134MiB/s][w=134 IOPS][eta 00m:57s]
Jobs: 4 (f=4): [w(4)][84.7%][w=126MiB/s][w=126 IOPS][eta 00m:46s]
Jobs: 4 (f=4): [w(4)][88.3%][w=125MiB/s][w=125 IOPS][eta 00m:35s]
Jobs: 4 (f=4): [w(4)][92.0%][w=145MiB/s][w=145 IOPS][eta 00m:24s]
Jobs: 4 (f=4): [w(4)][95.7%][w=131MiB/s][w=131 IOPS][eta 00m:13s]
Jobs: 4 (f=4): [w(4)][99.3%][w=125MiB/s][w=125 IOPS][eta 00m:02s]
Jobs: 4 (f=4): [w(4)][100.0%][w=125MiB/s][w=125 IOPS][eta 00m:00s]
fio_rw_1MiB_block_1GiB_4jobs: (groupid=0, jobs=4): err= 0: pid=17942: Thu Oct 30 11:54:53 2025
write: IOPS=125, BW=125MiB/s (131MB/s)(36.7GiB/300031msec); 0 zone resets
clat (usec): min=1892, max=102069, avg=31837.70, stdev=7527.12
lat (usec): min=1951, max=102132, avg=31899.31, stdev=7527.06
clat percentiles (msec):
| 1.00th=[ 4], 5.00th=[ 22], 10.00th=[ 26], 20.00th=[ 31],
| 30.00th=[ 32], 40.00th=[ 32], 50.00th=[ 32], 60.00th=[ 33],
| 70.00th=[ 33], 80.00th=[ 34], 90.00th=[ 36], 95.00th=[ 41],
| 99.00th=[ 61], 99.50th=[ 70], 99.90th=[ 91], 99.95th=[ 96],
| 99.99th=[ 101]
bw ( KiB/s): min=49152, max=383356, per=100.00%, avg=128461.80, stdev=5700.00, samples=2396
iops : min= 48, max= 374, avg=125.39, stdev= 5.56, samples=2396
lat (msec) : 2=0.01%, 4=1.03%, 10=0.95%, 20=2.32%, 50=93.67%
lat (msec) : 100=2.02%, 250=0.01%
cpu : usr=0.28%, sys=0.20%, ctx=37694, majf=0, minf=40
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=0,37613,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1
Run status group 0 (all jobs):
WRITE: bw=125MiB/s (131MB/s), 125MiB/s-125MiB/s (131MB/s-131MB/s), io=36.7GiB (39.4GB), run=300031-300031msec
Disk stats (read/write):
nvme1n1: ios=0/150458, merge=0/10, ticks=0/4308776, in_queue=4308776, util=100.00%
平均125MiBps、125IOPSであることが分かります。
CloudWatchからも確認します。
まずはVolumeAvgThroughputです。

確かにfioで書き込みをしている間、125MiBpsほどを示していますね。
続いて、VolumeAvgIOPSです。

fioの結果では125IOPSでしたが、こちらは500IOPSとなっています。
自分で計算する場合も500IOPSです。

また、1分間のサンプル数は常に1であることも分かります。

これはSSDのEBSボリュームのIOサイズの上限が256KiBだからです。256KiBよりも大きいブロックは256KiB単位で分割をして処理をします。
IOPS とは、1 秒あたりの入出力操作数を表す測定単位です。操作は KiB 単位で計測され、基礎となるドライブテクノロジーが1 つの I/O としてカウントするデータの最大量を決定します。I/O サイズは、SSD ボリュームで 256 KiB、HDD ボリュームで 1,024 KiB に制限されます。これは、小さい I/O やランダム I/O の扱いにおいて、SSD ボリュームは HDD ボリュームに比べて はるかに効率的であるためです。
小さな I/O 操作が物理的に連続している場合、Amazon EBS ではできる限りこれらを最大の I/O サイズになるまで、単一の I/O 操作にマージして処理します。同様に、I/O 操作が最大 I/O サイズより大きい場合、Amazon EBS ではより小さな I/O 操作に分割して処理しようとします。例をいくつか、次の表に示します。
ボリュームタイプ 最大 I/O サイズ アプリケーションからの I/O 操作 IOPS 数 コメント SSD 256 KiB 1 x 1024 KiB I/O 操作 4 (1,024 ÷ 256 = 4) Amazon EBS は、1,024 KiB の I/O オペレーションを 4 つの小さな 256 KiB オペレーションに分割します。 8 x シーケンシャル 32 KiB I/O 操作 1 (8 x 32 = 256) Amazon EBS は、8 つの連続した 32 KiB の I/O 操作を、1 つの 256 KiB の操作にマージします。 8 つのランダムな 32 KiB の I/O 操作 8 Amazon EBS は、ランダムな I/O 操作を個別にカウントします。
そのため、先ほどfio上ではブロックサイズを1MiBとしていました。1MiB / 256KiB = 4であるため、125IOPS × 4 = 500IOPSとなります。
30秒書き込みをしてみる
続いて、30秒書き込みをします。
今度はブロックサイズを256KiBにします。
$ date
Thu Oct 30 12:15:03 UTC 2025
$ sudo fio \
--directory=/mnt/vol/ \
--name fio_rw_256KiB_block_1GiB_4jobs \
--ioengine=psync \
--direct=1 \
--rw=randwrite \
--bs=256K \
--size=1G \
--numjobs=4 \
--runtime=30 \
--eta-newline=5 \
--time_based=1 \
--group_reporting \
--norandommap
fio_rw_256KiB_block_1GiB_4jobs: (g=0): rw=randwrite, bs=(R) 256KiB-256KiB, (W) 256KiB-256KiB, (T) 256KiB-256KiB, ioengine=psync, iodepth=1
...
fio-3.32
Starting 4 processes
fio_rw_256KiB_block_1GiB_4jobs: Laying out IO file (1 file / 1024MiB)
fio_rw_256KiB_block_1GiB_4jobs: Laying out IO file (1 file / 1024MiB)
fio_rw_256KiB_block_1GiB_4jobs: Laying out IO file (1 file / 1024MiB)
fio_rw_256KiB_block_1GiB_4jobs: Laying out IO file (1 file / 1024MiB)
Jobs: 4 (f=4): [w(4)][23.3%][w=125MiB/s][w=500 IOPS][eta 00m:23s]
Jobs: 4 (f=4): [w(4)][43.3%][w=125MiB/s][w=500 IOPS][eta 00m:17s]
Jobs: 4 (f=4): [w(4)][63.3%][w=125MiB/s][w=501 IOPS][eta 00m:11s]
Jobs: 4 (f=4): [w(4)][83.3%][w=125MiB/s][w=501 IOPS][eta 00m:05s]
Jobs: 4 (f=4): [w(4)][100.0%][w=125MiB/s][w=500 IOPS][eta 00m:00s]
fio_rw_256KiB_block_1GiB_4jobs: (groupid=0, jobs=4): err= 0: pid=26876: Thu Oct 30 12:15:35 2025
write: IOPS=517, BW=129MiB/s (136MB/s)(3882MiB/30009msec); 0 zone resets
clat (usec): min=963, max=10373, avg=7711.02, stdev=1834.40
lat (usec): min=978, max=10388, avg=7726.69, stdev=1834.51
clat percentiles (usec):
| 1.00th=[ 1434], 5.00th=[ 5669], 10.00th=[ 5866], 20.00th=[ 5997],
| 30.00th=[ 6128], 40.00th=[ 8029], 50.00th=[ 8848], 60.00th=[ 8979],
| 70.00th=[ 8979], 80.00th=[ 9110], 90.00th=[ 9241], 95.00th=[ 9372],
| 99.00th=[ 9896], 99.50th=[10028], 99.90th=[10159], 99.95th=[10159],
| 99.99th=[10421]
bw ( KiB/s): min=112640, max=383488, per=100.00%, avg=132608.00, stdev=8689.03, samples=236
iops : min= 440, max= 1498, avg=518.00, stdev=33.94, samples=236
lat (usec) : 1000=0.03%
lat (msec) : 2=1.49%, 4=3.25%, 10=94.76%, 20=0.46%
cpu : usr=0.42%, sys=0.44%, ctx=15544, majf=0, minf=45
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=0,15526,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1
Run status group 0 (all jobs):
WRITE: bw=129MiB/s (136MB/s), 129MiB/s-129MiB/s (136MB/s-136MB/s), io=3882MiB (4070MB), run=30009-30009msec
Disk stats (read/write):
nvme1n1: ios=0/15477, merge=0/0, ticks=0/118598, in_queue=118598, util=99.75%
$ date
Thu Oct 30 12:15:36 UTC 2025
平均129MiBps、517IOPSです。
VolumeAvgThroughputとVolumeAvgIOPSのメトリクスを確認します。


はい、64MiBpsと259IOPSと半分になっています。
これがいずれのメトリクスも1分間の平均を記録するものだからです。今回は30秒書き込んだため、fioの結果の半分となっています。
つまりは、マイクロバーストのような60秒未満の瞬間的な挙動は気付きづらいです。これは従来のやり方でも同様ですがが気をつけましょう。
パッとEBSボリュームのIOPSとスループットを把握したいときに
EBSボリュームで1分間の平均IOPSとスループットを表すCloudWatchメトリクスが追加されたアップデートを紹介しました。
パッとEBSボリュームのIOPSとスループットを把握したいときに非常に便利です。
なお、今までのように書き込み/読み込みの量や操作数から把握する方法が全く無駄になったという訳ではありません。今回追加されたいずれのメトリクスも読み取りと書き込みの区別はされていません。そのため、読み取りと書き込みのどちらの処理が重く性能が出ていないのかを把握したい場合などには変わらず必要な指標となります。ケースバイケースで使い分けましょう。
この記事が誰かの助けになれば幸いです。
以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!






