Skip to main content

Checking USB Device Speed in Linux

Monday, April 10, 2023
Reading time 5 minutes

Just a week ago I took personal storage to another level by buying myself a DAS. For those who don’t know, a DAS is essentially a box where you can store several hard drives and access them, usually via USB or eSATA. Among the things you can do with this type of device mainly include having 2, 4, or 8 hard drives available for the operating system (i.e., as secondary storage), which makes things much easier if you have software like Plex, which normally feeds on enormous amounts of data for which a single hard drive may no longer be sufficient.

The thing is that the DAS I acquired supports USB 3.0. Theoretically, USB 3 transfer speeds reach up to 5 Gbit/s. This obviously doesn’t hold true in practice, especially when dealing with mechanical disks, which have their speed more restricted by the type of hard drive than by the maximum speed of the USB protocol itself. But when I started transferring files from a somewhat older hard drive to a new one I acquired along with the DAS, I encountered a surprise. The speed I could see in the transfers, these being performed on the same computer (going from a local disk to the DAS), were approximately 35-43 MBPS (280-344 Mbit/s). These speeds were much less than what I expected from the protocol, especially considering the DAS is running with disks formatted in the file system that seems to be fastest for Linux: EXT-4.

The first thing that occurred to me to check was whether the DAS cable was connected to the USB 3 port. Although this mere verification has been somewhat more complex than I imagined, mainly for two reasons. The Mini PC that acts as a server has 2 USB 2 ports and another 2 USB 3 ports, and I don’t have functional eyes available to check which of the USB connectors have the USB 3 signals. So my second plan was to check if the operating system had a way to tell me if it was running under USB 2 or 3.

These notes have only been tested on Debian, as it’s the system running the server. Although I imagine it will work similarly on other systems.

Step 1. Getting USB device information

The first thing to do is get some information about the USB devices that are already connected to the system. For this, you can simply use the lsusb command, like this:

$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 152d:0567 JMicron Technology Corp. / JMicron USA Technology Corp. JMS567 SATA 6Gb/s bridge
Bus 001 Device 003: ID 0bda:c821 Realtek Semiconductor Corp. Bluetooth Radio
Bus 001 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Special attention must be paid here, as other devices, like the bluetooth adapter, may appear since in theory they communicate internally as just another USB device. In my case, the device I’m interested in is easy to identify, as it literally says in its product description “SATA 6Gb/s bridge”. The line for that device is the following:

Bus 001 Device 004: ID 152d:0567 JMicron Technology Corp. / JMicron USA Technology Corp. JMS567 SATA 6Gb/s bridge

From this line, we’ll only be interested in taking 2 pieces of data, the manufacturer ID and the product ID. It’s the pair of data separated by a colon. In my case, the manufacturer ID is 152d, and the product ID is 0567. That’s all we need to know about this command to know the reported speed at which the device will be working on the port where we’ve connected it.

Step 2. Query devices

The next thing to do is search for the device in the /sys/devices directory. For this we’ll use the manufacturer ID, and the result will basically be the path to another location, which we’ll use in step 3 to definitively know the possible speed. Here you have to keep in mind that this speed we’ll query is not what the device can support, but what has been negotiated in this particular connection.

To search for the device with manufacturer ID 152d, you have to execute this command. Replace 152d with your device’s manufacturer ID:

# find /sys/devices/ -name idVendor -print -exec cat {} \; | grep -B 1 152d
/sys/devices/pci0000:00/0000:00:15.0/usb1/1-6/idVendor
152d

From the response we’re only interested in the first line, which is a full path to a file. You’ll have to copy it to be able to know the speed.

Step 3. Query device speed

With the path we copied in step 2, you just have to use the cat command to read that file, replacing the last component, called idVendor, with the word “speed”. In my case, the path and command would look like this:

# cat /sys/devices/pci0000:00/0000:00:15.0/usb1/1-6/speed

If everything goes well, you’ll be able to see a number on screen, which indicates the maximum speed at which file transfer can be sustained on the device. If the number is 480, it’s a USB 2.0 connection, if it’s 5000, it’s USB 3. In my case the result was 480, which would explain the speeds closer to USB 2 than USB 3. To correct this situation, it’s only necessary to change the device’s connection to another port and check again with the steps explained here.

Linux Administration NAS

NAS USB Speed