WRITELOOP

HOW TO FIX FOR GENERAL SLOWNESS WHEN PLUGGING AN HDD TO A LINUX MACHINE (ENDEAVOUROS)

When setting up my new zimablade for backups, I found out that everytime I operated on my external HDD on a USB 3.0 Enclosure the machine was fully taken to a halt. System (EndeavourOS) would freeze for some seconds, commands would become slow, etc. This is how I solved that.

2026 April 14

The Cause

The system was freezing because multiple background processes were continuously and unknowingly waking the spinning HDD, causing repeated I/O stalls over the slow USB connection.

Things like the mlocate indexer and the kernel’s own file access timestamp writes were constantly poking the drive without any obvious reason.

The fix tackles this on three fronts:

A) Mounting the drive with noatime and lazytime eliminates unnecessary writes triggered by simple file reads; B) Excluding the HDD paths in updatedb.conf stops the locate daemon from scanning and waking it during background indexing; C) Configuring hd-idle makes the drive spin down automatically after 10 minutes of inactivity.

Together, these changes ensure the HDD only wakes up when you actually need it, putting an end to the random freezes.

The fix, step-by-step

  1. Mount the HDD with noatime,lazytime on /etc/fstab. E.g.:
UUID=3bffb7d4-1294-4bdd-9f84-d9a5c52125c7       /media/XTORAGE-2TB      ext4    defaults,nofail,noatime,lazytime        0 0

Also, edit /etc/updatedb.conf to not index the files on the HDD using locate/locatedb:

# Disables for the HDD partitions
PRUNEPATHS = "/media/XTORAGE-2TB /media/XTORAGE-5TB"
  1. Install hd-idle: sudo yay -S hd-idle --noconfirm

  2. Use sudo lsblk to get the disk id (on this session: sda, sdb, etc…). E.g.:


(ins)❯ sudo lsblk
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda            8:0    0 931,5G  0 disk
└─sda1         8:1    0 931,5G  0 part /storage
sdb            8:16   0   7,3T  0 disk  //---------------------> this is my HDD
├─sdb1         8:17   0   2,4T  0 part
└─sdb2         8:18   0   4,9T  0 part
mmcblk0      179:0    0  29,1G  0 disk
├─mmcblk0p1  179:1    0  26,2G  0 part /
└─mmcblk0p2  179:2    0   2,9G  0 part [SWAP]
mmcblk0boot0 179:8    0     4M  1 disk
mmcblk0boot1 179:16   0     4M  1 disk
  1. Then, use ls -l /dev/disk/by-id/ to get the id of the disk. Use anything that starts with ata. E.g.:

(ins)❯ sudo ls -l /dev/disk/by-id/ | grep sdb
lrwxrwxrwx 1 root root  9 mar 31 07:35 ata-ST8000DM004-2CX188_ZR14EYJK -> ../../sdb
lrwxrwxrwx 1 root root 10 mar 31 07:35 ata-ST8000DM004-2CX188_ZR14EYJK-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 mar 31 07:35 ata-ST8000DM004-2CX188_ZR14EYJK-part2 -> ../../sdb2
lrwxrwxrwx 1 root root  9 mar 31 07:35 usb-External_USB_3.0_2018033100138-0:0 -> ../../sdb
lrwxrwxrwx 1 root root 10 mar 31 07:35 usb-External_USB_3.0_2018033100138-0:0-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 mar 31 07:35 usb-External_USB_3.0_2018033100138-0:0-part2 -> ../../sdb2
lrwxrwxrwx 1 root root  9 mar 31 07:35 wwn-0x5000c500e5e6ebeb -> ../../sdb
lrwxrwxrwx 1 root root 10 mar 31 07:35 wwn-0x5000c500e5e6ebeb-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 mar 31 07:35 wwn-0x5000c500e5e6ebeb-part2 -> ../../sdb2
  1. Edit /etc/hd-idle.conf and config it to spin down after X minutes of inactivity only. E.g.:

# Spin down the Seagate 8TB after 10 minutes of inactivity
# Default idle time is disabled for all other drives
HD_IDLE_OPTS="-i 0 -a /dev/disk/by-id/ata-ST8000DM004-2CX188_ZR14EYJK -i 600"
  1. Enable hd-idle service: sudo systemctl enable --now hd-idle

  2. Check if the service runs, it will probably not detect the settings yet:


(ins)❯ sudo systemctl status hd-idle
● hd-idle.service - Hard drive idling daemon
     Loaded: loaded (/usr/lib/systemd/system/hd-idle.service; enabled; preset: disabled)
     Active: active (running) since Tue 2026-03-31 07:52:47 -03; 5min ago
 Invocation: 7832483ca0ba49a38e7f31e5f3cef4fe
   Main PID: 53824 (hd-idle)
      Tasks: 1 (limit: 9289)
     Memory: 180K (peak: 1.8M)
        CPU: 13ms
     CGroup: /system.slice/hd-idle.service
             └─53824 /usr/sbin/hd-idle -d

mar 31 07:52:47 oa systemd[1]: Started Hard drive idling daemon.
mar 31 07:52:47 oa (hd-idle)[53824]: hd-idle.service: Referenced but unset environment variable evaluates to an empty string: HD_IDLE_OPTS

So, to fix that, we must edit the systemd service and point it to the file:

A) sudo systemctl edit hd-idle

B) Add this line on the editor position that opens:


[Service]
EnvironmentFile=/etc/hd-idle.conf

Then, save and quit the editor, and then:

C) Restart the service fully:


sudo systemctl daemon-reload && sudo systemctl restart hd-idle && sudo systemctl status hd-idle

You should then see an output similar to this:


● hd-idle.service - Hard drive idling daemon
     Loaded: loaded (/usr/lib/systemd/system/hd-idle.service; enabled; preset: disabled)
    Drop-In: /etc/systemd/system/hd-idle.service.d
             └─override.conf
     Active: active (running) since Tue 2026-03-31 08:05:41 -03; 61ms ago
 Invocation: 0782bca4cea84fc183f8d6345bb04140
   Main PID: 67269 (hd-idle)
      Tasks: 1 (limit: 9289)
     Memory: 180K (peak: 1.7M)
        CPU: 12ms
     CGroup: /system.slice/hd-idle.service
             └─67269 /usr/sbin/hd-idle -d -i 0 -a /dev/disk/by-id/ata-ST8000DM004-2CX188_ZR14EYJK -i 600