How to check the performance of a hard drive (Either via terminal or GUI). The write speed. The read speed. Cache size and speed. Random speed.

up vote 360 down vote accepted

Terminal method

hdparm is a good place to start.

sudo hdparm -Tt /dev/sda

/dev/sda:
Timing cached reads:   12540 MB in  2.00 seconds = 6277.67 MB/sec
Timing buffered disk reads: 234 MB in  3.00 seconds =  77.98 MB/sec

sudo hdparm -v /dev/sda will give information as well.

dd will give you information on write speed.

If the drive doesn't have a file system (and only then), use of=/dev/sda.

Otherwise, mount it on /tmp and write then delete the test output file.

dd if=/dev/zero of=/tmp/output bs=8k count=10k; rm -f /tmp/output

10240+0 records in
10240+0 records out
83886080 bytes (84 MB) copied, 1.08009 s, 77.7 MB/s

Graphical method

  1. Go to System -> Administration -> Disk Utility.
    • Alternatively, launch the Gnome disk utility from the command line by running gnome-disks
  2. Select your hard disk at left pane.
  3. Now click “Benchmark – Measure Drive Performance” button in right pane.
  4. A new window with charts opens.You will find and two buttons. One is for “Start Read Only Benchmark” and another one is “Start Read/Write Benchmark”. When you click on anyone button it starts benchmarking of hard disk.

test

How to benchmark disk I/O

Article

Is there something more you want?

  • 5
    I would recommend testing /dev/urandom as well as /dev/zero as inputs to dd when testing an SSD as the compressibility of the data can have a massive effect on write speed. – Ian Mackinnon Nov 8 '12 at 16:23
  • 3
    There is no such "System ->" on my Ubuntu 12.04 Unity. Or at least I haven't found it. And I do not see that disk tool neither within System Settings... O_o But I finallly managed to run it: /usr/bin/palimpsest – Fran Marzoa Nov 30 '12 at 22:00
  • 5
    Note that since 12.10 it's simply called Disks and can be found through Unity. – Paul Lammertsma Feb 14 '14 at 11:18
  • 1
    On Gnome this has moved to Applications --> System Tools --> Preferences --> Disk Utility. For those of use who hate Unity. – Ken Sharp Mar 13 '14 at 15:12
  • 2
    The /tmp filesystem is often using a ramdisk these days. So writing to /tmp would seem to be testing your memory, not your disk subsystem. – Zoredache Mar 27 '14 at 16:44

Suominen is right, we should use some kind of sync; but there is a simpler method, conv=fdatasync will do the job:

dd if=/dev/zero of=/tmp/output conv=fdatasync bs=384k count=1k; rm -f /tmp/output
1024+0records in
1024+0 records out
402653184 bytes (403 MB) copied, 3.19232 s, 126 MB/s
  • 27
    It's an answer using a different command/option than the others. I see it's an answer worthy of a post of its own. – Alaa Ali Aug 18 '13 at 19:01
  • 2
    Why have you used 384k as block size? – Diego F. Durán Jun 2 '14 at 14:39
  • 1
    @Diego There is no reason. It was just an example. You can use anything else. (between about 4k ... 1M ) Of course bigger blocksize will give better performance. And of course decrease the count number when you use big bs, or it will take a year to finish. – Tele Jul 25 '14 at 0:17
  • it's not reliable by bench mark tools like iozone and sysbench numbers are much much lower – MSS Aug 27 '16 at 10:00
  • Be careful with using zeros for your write data - some filesystems and disks will have a special case path for it (and other compressible data) which will cause artificially high benchmark numbers... – Anon 17 hours ago

I would not recommend using /dev/urandom because it's software based and slow as pig. Better to take chunk of random data on ramdisk. On hard disk testing random doesn't matter, because every byte is written as is (also on ssd with dd). But if we test dedupped zfs pool with pure zero or random data, there is huge performance difference.

Another point of view must be the sync time inclusion; all modern filesystems use caching on file operations.

To really measure disk speed and not memory, we must sync the filesystem to get rid of the caching effect. That can be easily done by:

time sh -c "dd if=/dev/zero of=testfile bs=100k count=1k && sync"

with that method you get output:

sync ; time sh -c "dd if=/dev/zero of=testfile bs=100k count=1k  && sync" ; rm testfile 
1024+0 records in
1024+0 records out
104857600 bytes (105 MB) copied, 0.270684 s, 387 MB/s

real    0m0.441s
user    0m0.004s
sys 0m0.124s

so the disk datarate is just 104857600 / 0.441 = 237772335 B/s --> 237MB/s

That is over 100MB/s lower than with caching.

Happy benchmarking,

  • Thanks for highlighting the sync issue! – Dina 2 days ago
  • Be careful with using zeros for your write data - some disks (such as SSDs) and some filesystems will have a special case path for it. This results in artificially high benchmark numbers when using zero buffers. Other highly compressible data patterns can also distort results... – Anon 17 hours ago

If you want to monitor the disk read and write speed real-time you can use the iotop tool.

This is useful to get exact information about how a disk performs for a particular application or task. The output will show you read/write speed per process, and total read/write speed for the server, much similar to top.

To install iotop:

sudo apt-get install iotop  

To run it:

sudo iotop

bonnie++ is the ultimate benchmark utility I know for linux.

(I'm currently preparing a linux livecd at work with bonnie++ on it to test our windows-based machine with it!)

It takes care of the caching, syncing, random data, random location on disk, small size updates, large updates, reads, writes, etc. Comparing a usbkey, a harddisk (rotary), a solid-state drive and a ram-based filesystem can be very informative for the newbie.

I have no idea if it is included in Ubuntu, but you can compile it from source easily.

http://www.coker.com.au/bonnie++/

Write speed

$ dd if=/dev/zero of=./largefile bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 4.82364 s, 223 MB/s

Block size is actually quite large. You can try with smaller sizes like 64k or even 4k.


Read speed

Run the following command to clear the memory cache

$ sudo sh -c "sync && echo 3 > /proc/sys/vm/drop_caches"

Now read the file which was created in write test:

$ dd if=./largefile of=/dev/null bs=4k
165118+0 records in
165118+0 records out
676323328 bytes (676 MB) copied, 3.0114 s, 225 MB/s
  • Be careful with using zeros for your write data - some filesystems and disks will have a special case path for it (and other compressible data) which will cause artificially high benchmark numbers... – Anon 17 hours ago

some hints on how to use bonnie++

bonnie++ -d [TEST_LOCATION] -s [TEST_SIZE] -n 0 -m [TEST_NAME] -f -b -u [TEST_USER] 
bonnie++ -d /tmp -s 4G -n 0 -m TEST -f -b -u james

A bit more at: SIMPLE BONNIE++ EXAMPLE.

If you want accuracy, you should use fio. It requires reading the manual (man fio) but it will give you accurate results. Note that for any accuracy, you need to specify exactly what you want to measure. Some examples:

Sequential READ speed with big blocks (this should be near the number you see in the specifications for your drive):

fio --name TEST --eta-newline=5s --filename=fio-tempfile.dat --rw=read --size=500m --io_size=10g --blocksize=1024k --ioengine=libaio --fsync=10000 --iodepth=32 --direct=1 --numjobs=1 --runtime=60 --group_reporting

Sequential WRITE speed with big blocks (this should be near the number you see in the specifications for your drive):

fio --name TEST --eta-newline=5s --filename=fio-tempfile.dat --rw=write --size=500m --io_size=10g --blocksize=1024k --ioengine=libaio --fsync=10000 --iodepth=32 --direct=1 --numjobs=1 --runtime=60 --group_reporting

Random 4K read QD1 (this is the number that really matters for real world performance unless you know better for sure):

fio --name TEST --eta-newline=5s --filename=fio-tempfile.dat --rw=randread --size=500m --io_size=10g --blocksize=4k --ioengine=libaio --fsync=1 --iodepth=1 --direct=1 --numjobs=1 --runtime=60 --group_reporting

Mixed random 4K read and write QD1 with sync (this is worst case number you should ever expect from your drive, usually 1-10% of the number listed in the spec sheet):

fio --name TEST --eta-newline=5s --filename=fio-tempfile.dat --rw=randrw --size=500m --io_size=10g --blocksize=4k --ioengine=libaio --fsync=1 --iodepth=1 --direct=1 --numjobs=1 --runtime=60 --group_reporting

Increase the --size argument to increase the file size. Using bigger files may reduce the numbers you get depending on drive technology and firmware. Small files will give "too good" results for rotational media because the read head does not need to move that much. If your device is near empty, using file big enough to almost fill the drive will get you the worst case behavior for each test. In case of SSD, the file size does not matter that much.

Note that fio will create the required temporary file on first run. It will be filled with random data to avoid getting too good numbers from devices that cheat by compressing the data before writing it to permanent storage. The temporary file will be called fio-tempfile.dat in above examples and stored in current working directory. So you should first change to directory that is mounted on the device you want to test.

  • 1
    I just re-tested some devices. Using above sequential read test (2MB block size) I got 280 MB/s from Samsung SSD 850 EVO and 1070 MB/s from Intel 910 SSD. With 64k block size and otherwise identical commandline I got 268 MB/s from 850 EVO and 1055 MB/s from 910 SSD. At least for this kind of devices, using 2 MB block size seems to improve results around 1-5% even though it causes kernel to split requests to hardware. I guess even with kernel optimizations the overhead of submitting more syscalls is worse than splitting inside kernel. – Mikko Rantalainen Jun 26 at 7:07
  • 1
    Upon further testing it seems that I get the highest sequential throughput using power of 2 value that is less than max_sectors_kb. I changed the above example commands to use 1 MB block size because that seems to work with real world hardware. And I also tested that fsync does not matter for reading. – Mikko Rantalainen Jun 26 at 7:18
  • 1
    Depending on how the drive is connected you may find that your iodepth was too low. You would have to watch what Linux is actually sending down to the device and what depth it's doing it at... – Anon Jun 26 at 20:28
  • 1
    I set iodepth to 1 for random access exactly because real world programs often run algorithms/logic that does not work with depth any higher than 1. As a result, if such depth is "too low" your I/O device is bad. It's true that some SSD devices will benefit from depth higher than 32. However, can you point to any real world workload that requires read access and is able to keep up iodepth higher than 32? TL; DR: if you want to reproduce some insanely high read benchmark number with high latency device, use iodepth=256 --numjobs=4 but never expect to see such numbers for real. – Mikko Rantalainen Jul 3 at 7:46
  • 1
    Most "real world" programs aren't actually submitting I/O (o_)directly let alone asynchronously so all of our examples are in unusual workloads to push the limits benchmark territory (as they say, the best benchmark is your real workload). Having said that doing things like running multiple busy virtual machines are easily able to generate workloads with crazy high depths but where the I/O often looks random from the disk perspective and is a simple example of where you can see a huge speedup from things like NVMe. PS: setting numbers too high will reduce throughput so there's a sweet spot... – Anon Jul 4 at 18:33

protected by Community Feb 12 '14 at 16:23

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.