Open-source project
adelolmo/hd-idle avatar
adelolmo/hd-idle

hd-idle spins down the external disks your enclosure forgot about

Hard Disk Idle Spin-Down Utility

742 stars47 forksGoGPL-3.0

At a glance

What is it?
hd-idle is a Go reimplementation of Christian Mueller's hd-idle that watches disk activity and issues standby commands to drives that cannot be told to idle by themselves, with the added ability to speak ATA directly and to judge activity at the partition or device mapper level.
Who is it for?
hd-idle suits a Linux user with USB enclosures whose drives never power down, and it suits a NAS or backup box where a spinning disk is both a noise and a power problem. It is the wrong tool for a machine with no external disks, since the whole point is the enclosure that ignores the idle timer, and it is the wrong tool if you rely on smartmontools, because the readme states the program is not compatible with disk monitoring tools like smartmontools.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 117 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem is enclosures that ignore the idle timer

The premise is narrow and specific. hd-idle is a utility program for spinning-down external disks after a period of idle time, and the reason it is needed is that most external IDE disk enclosures do not support setting the IDE idle timer, so a program like this is required to spin down idle disks automatically. The project is a reimplementation of Christian Mueller's hd-idle with some extra features, and it is a Go program, which matters for the deployment story. There is one warning that should be read before anything else, which is that hd-idle is not compatible with the usage of disk monitoring tools like smartmontools. The activity accounting the program performs and the counters a monitoring tool reads are not compatible, so running both on the same machine is a decision rather than an oversight.

ATA support exists because the SCSI path does not cover everything

The original implementation written by Christian Mueller relies on the SCSI api to work, and when listing drives by id the disks starting with usb stop using the original implementation while the disks starting with ata do not.

$ ls /dev/disk/by-id/ ata-WDC_WD40EZRX- ata-WDC_WD50EZRX- usb-WD_My_Book_1140_

The feature the reimplementation adds is ATA command support, so that the same api calls hdparm uses can be replicated. hdparm always stops the drives without any problems because it uses ATA api calls to send disks to standby, and hd-idle comes with ATA commands support to replicate that behaviour. The practical effect is that a USB enclosure that appears as a USB device by id can be driven through the ATA path when the SCSI one does not work, which is the common failure case for external drives.

Activity detection moved to partitions because kernels changed the counters

The trickiest of the extra features is the change in how activity is calculated. The disk activity is calculated by watching read and write changes on partition or device mapper level instead of disk level, and this is required for kernels newer than 5.4 LTS, because disk monitoring tools change the read and write values on disk level although there is no real activity on the disk itself. The knock-on effect is that when using LUKS, the activity happens on the device mapper device mapped to the corresponding disk, so a fully encrypted volume is invisible to the disk level counters and the program has to look one level down. Two smaller features are also listed. The first monitors the skew between monitoring cycles, identifying if the sleep took longer than expected and resetting the spun down flag if it waited too long for the main loop sleep, which is described as capturing suspend events as well as excessive machine load. The second resolves disk symlinks in runtime, so disks added after the application starts are not hidden.

Building it is a clone and a make, and the Makefile picks your architecture

Precompiled binaries for released versions are available in the releases section, so building is not always necessary. When it is, you need a working Go environment with version 1.16 or greater installed, and the commands are short.

git clone https://github.com/adelolmo/hd-idle cd hd-idle make

The Makefile is where the cross compilation lives, mapping uname output to a Go architecture, with x86_64 to amd64, aarch64 to arm64 and armv7l to armhf, and it errors out on an unrecognised architecture rather than guessing. The build sets GOOS to linux explicitly, and the install target puts the binary under sbin and the man page under share/man/man8, with DESTDIR honoured for packaging, which is how the Debian build works. The Debian package can also be built directly with dpkg-buildpackage for armhf, i386, amd64 or arm64 by substituting the -a parameter. The go.mod is minimal, with a single dependency on benmcclelland/sgio, which is the SCSI generic interface library.

Running it means picking a device policy and an idle time

Running the program with no arguments starts it with the default options, causing all SCSI hard disks, which includes USB, Firewire and SCSI, to spin down after 10 minutes of inactivity. The command line options are the configuration surface. The -a option sets the device name of disks for subsequent idle-time parameters, and it can also be a symlink such as a path under /dev/disk/by-uuid, and there is a default entry for all disks not named otherwise. The -i option sets the idle time in seconds for the currently named disks or for all disks, and setting it to 0 means the disks never spin down. The -c option chooses the api call used to stop the device, either scsi as the default or ata. The -s option sets the symlink policy, where 0 resolves symlinks only on start and 1 also resolves them at runtime until success, and by default symlinks are only resolved on start, with the default configuration applied if a symlink does not resolve to a device. The -l option names a logfile, written only after a disk has spun up or down, with the warning that this option might cause the disk holding the logfile to spin up because another disk had activity.

The power condition flag is where SAS users get hurt

The -p option sets the power condition sent with the issued SCSI START STOP UNIT command, and the values run from 0 to 15 inclusive. The default value of 0 works fine for disks accessible via the SCSI layer such as USB and IEEE 1394, but it will not work as intended with real SCSI or SAS disks. The reason given is specific and worth knowing: a stopped SAS disk will not start up automatically on access, and requires a startup command for reactivation. For SAS disks the useful values are 2 for idle and 3 for standby. This is the single most consequential option in the tool, because getting it wrong on a SAS array means the disks stop and do not come back on their own. The troubleshooting section in the readme has a matching entry for a SCSI response that is not ok, and a separate note on LUKS support, which follows from the partition level activity detection described earlier.

Where this is the wrong tool

Three limits are worth stating plainly. The first is that it only helps with drives that cannot be told to idle themselves, so on a machine whose internal drives support the idle timer natively it does nothing you could not have configured in the firmware. The second is the smartmontools incompatibility, which is not a small conflict, because the program and the monitoring tool both want to read and reset the same disk counters and they interfere. The third is the risk in the feature itself. Spinning a disk down while something is still using it, or with a file system that was not cleanly unmounted, risks filesystem corruption, which is why the readme has a dedicated warning section on spinning down disks and a troubleshooting section for disks that will not spin down. A cautious deployment applies the idle time generously, watches the logfile at first, and keeps the partition level detection on so that a busy volume is not mistaken for an idle one.

Editorial conclusion

hd-idle suits a Linux user with USB enclosures whose drives never power down, and it suits a NAS or backup box where a spinning disk is both a noise and a power problem. It is the wrong tool for a machine with no external disks, since the whole point is the enclosure that ignores the idle timer, and it is the wrong tool if you rely on smartmontools, because the readme states the program is not compatible with disk monitoring tools like smartmontools. Before running it, read the warning about spinning down disks, and check how your kernel reports activity, since the partition level detection exists precisely because newer kernels change the disk level counters even when the disk itself is idle. The last push was on 2026-06-28 and the newest tag is v1.22, which the release notes mark as for testing only.

Frequently asked questions

What is hd-idle and why would I need it?

It is a utility that spins down external disks after a period of idle time, and it exists because most external IDE disk enclosures do not support setting the IDE idle timer, so a program is required to spin down idle disks automatically. The README warns that it is not compatible with disk monitoring tools like smartmontools.

How do I build hd-idle from source?

You need a working Go environment with version 1.16 or greater, then run git clone https://github.com/adelolmo/hd-idle, cd hd-idle and make. The Makefile selects the target architecture from uname, and on Debian you can also build a package with dpkg-buildpackage for armhf, i386, amd64 or arm64.

Why do my disks not spin down with hd-idle?

The README notes that hd-idle uses /proc/diskstats to read disk statistics, and if that file is not present the program will not work. It also has separate troubleshooting entries for disks that will not spin down, for LUKS support, and for a SCSI response that is not ok, and the -d debug option gives more information when there are problems.

Official sources

  1. adelolmo/hd-idle on GitHub
  2. Issues
  3. License: GPL-3.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/adelolmo-hd-idle.svg)](https://hysenlabs.com/projects/adelolmo-hd-idle)

Was this useful?