I upgraded my Raspberry Pi to use an external SSD drive instead of its built-in SD card reader. If you use your little computer for anything non-trivial, so should you.

For boring old dd sequential reads, the SSD is several times faster than the SD card:

# dd if=/dev/mmcblk0 of=/dev/null bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 24.8316 s, 42.2 MB/s

# dd if=/dev/sda of=/dev/null bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 3.4034 s, 308 MB/s

That’s probably not enough to be worth bothering with, though. I’d guess that most people who need high throughput have either come to this conclusion on their own, or weren’t using a Raspberry Pi anyway.

An SSD make an enormous difference when multiple processes are trying to write at once. This happens on real-world systems when running routine maintenance tasks like apt-get upgrade, and seeing other jobs freeze up while waiting their turn to write to disk.

I used sysbench to simulate concurrent random IO workloads. The sequential writing “prepare” step is proportionally faster on the SSD:

/tmp/sdcard-bench$ sysbench fileio prepare
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)

128 files, 16384Kb each, 2048Mb total
Creating files for the test...
Extra file open flags: (none)
Creating file test_file.0
Creating file test_file.1
Creating file test_file.2
...
Creating file test_file.125
Creating file test_file.126
Creating file test_file.127
2147483648 bytes written in 120.50 seconds (17.00 MiB/sec).

/tmp/ssd-bench$ sysbench fileio prepare
...
Creating file test_file.127
2147483648 bytes written in 30.82 seconds (66.45 MiB/sec).

That’s a nice bump, but I wouldn’t have gone through the trouble for that alone. The testing stage looks much different. Here’s the SD card’s benchmark:

/tmp/sdcard-bench$ sysbench fileio --file-test-mode=rndrw --threads=10 run
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 10
Initializing random number generator from current time


Extra file open flags: (none)
128 files, 16MiB each
2GiB total file size
Block size 16KiB
Number of IO requests: 0
Read/Write ratio for combined random IO test: 1.50
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random r/w test
Initializing worker threads...

Threads started!


File operations:
    reads/s:                      81.51
    writes/s:                     53.74
    fsyncs/s:                     283.74

Throughput:
    read, MiB/s:                  1.27
    written, MiB/s:               0.84

General statistics:
    total time:                          11.0830s
    total number of events:              3367

Latency (ms):
         min:                                    0.01
         avg:                                   32.51
         max:                                 1929.04
         95th percentile:                      155.80
         sum:                               109474.32

Threads fairness:
    events (avg/stddev):           336.7000/23.91
    execution time (avg/stddev):   10.9474/0.30

And the SSD’s:

/tmp/ssd-bench$ sysbench fileio --file-test-mode=rndrw --threads=10 run
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 10
Initializing random number generator from current time


Extra file open flags: (none)
128 files, 16MiB each
2GiB total file size
Block size 16KiB
Number of IO requests: 0
Read/Write ratio for combined random IO test: 1.50
Periodic FSYNC enabled, calling fsync() each 100 requests.
Calling fsync() at the end of test, Enabled.
Using synchronous I/O mode
Doing random r/w test
Initializing worker threads...

Threads started!


File operations:
    reads/s:                      1535.98
    writes/s:                     1023.49
    fsyncs/s:                     3402.13

Throughput:
    read, MiB/s:                  24.00
    written, MiB/s:               15.99

General statistics:
    total time:                          10.1136s
    total number of events:              59047

Latency (ms):
         min:                                    0.01
         avg:                                    1.69
         max:                                   14.35
         95th percentile:                        4.03
         sum:                                99904.56

Threads fairness:
    events (avg/stddev):           5904.7000/29.24
    execution time (avg/stddev):   9.9905/0.00

The SSD card is approximate 20 times faster than the SD card, and the SD card’s maximum latency is about 140 times higher than the SSD’s. In normal operation, this has an enormous effect on usability. It’s the difference between the system slowing down a little during intensive operations, and everything hanging for seconds at a time.

I wish I’d done this sooner.