🚀 Executive Summary

TL;DR: ZFS’s default Copy-on-Write behavior and frequent Transaction Group (TXG) flushes prevent spinning drives from entering standby, leading to increased power consumption and noise. Solutions involve disabling ‘atime’, using the ‘hd-idle’ daemon for forced SCSI spindown, and cautiously increasing the ‘zfs_txg_timeout’ kernel parameter to buffer writes longer.

🎯 Key Takeaways

  • ZFS’s default `atime=on` setting and 5-second Transaction Group (TXG) flush cycle generate constant disk activity, preventing drives from spinning down.
  • The `hd-idle` daemon provides a reliable solution for forcing SCSI spindown commands, especially effective where `hdparm -S` fails on ZFS arrays or with SAS HBAs.
  • Adjusting the `zfs_txg_timeout` kernel parameter to a higher value (e.g., 30-300 seconds) can significantly reduce write frequency, but increases the risk of data loss during power failure.

Making drives with ZFS spin down

Quick Summary: ZFS defaults create a constant stream of writes that prevent spinning disks from entering standby, driving up power costs and noise levels. Here is how I tune access times, implement dedicated spindown tools, and tweak kernel parameters to finally let your arrays sleep.

Taming the Beast: Making ZFS Drives Actually Spin Down

I still remember the first time I built a serious storage server for my home lab, affectionately named archive-node-01. It was packed with twelve 10TB HGST Ultrastars—enterprise drives that are built like tanks but sound like a bag of marbles in a dryer when they are seeking. I felt like a genius architect until the first night I tried to sleep. The rack was in the basement, yet I could hear the rhythmic click-chunk every five seconds. It wasn’t just the noise; my power bill that month looked like a ransom note.

I learned the hard way what I’m about to tell you: ZFS is an insomniac by design.

If you are struggling to get your drives to spin down, you aren’t crazy, and your hardware probably isn’t broken. You are just fighting against a filesystem designed for servers that never sleep.

The “Why”: It’s Not a Bug, It’s a Feature

To fix this, you have to understand why ZFS behaves this way. ZFS is a Copy-on-Write (CoW) filesystem. It doesn’t write data to the disk the moment you hit “save.” Instead, it buffers writes into RAM and flushes them to the disk in a “Transaction Group” (TXG). By default, ZFS flushes this buffer every 5 seconds.

Furthermore, ZFS loves metadata. Even if you just look at a file, ZFS wants to update the access time (atime). Between the 5-second flush cycle, the metadata updates, and background scrubs, your drives never get the 15-20 minutes of silence usually required for internal firmware to trigger standby mode.

Here are the three ways I handle this at TechResolve, ranging from basic hygiene to “voiding your warranty.”

Solution 1: The Hygiene Fix (Start Here)

Before installing fancy tools, we need to stop ZFS from writing to the disk just because you listed a directory. By default, atime is on. This kills spindown. If you have a dataset like tank/media where you mostly just read files, turn this off immediately.

Run this on your active datasets:

# Check the current setting
zfs get atime tank/media

# Turn it off (Read operations won't trigger a write)
zfs set atime=off tank/media

Also, check your System Dataset. If you are running TrueNAS or a similar appliance, the OS often puts logs on the storage pool. If your system logs are writing to the spinning rust, they will never sleep. Move your system dataset to your boot SSDs.

Solution 2: The Permanent Fix (hd-idle)

If you have ever tried using hdparm -S on a ZFS array, you probably noticed it doesn’t work reliably, especially if you are using a SAS HBA (Host Bus Adapter). The drives ignore the command or wake up immediately.

My go-to tool for this is hd-idle. It sits as a daemon, monitors disk activity at the OS level, and issues a forced SCSI spindown command when the timer hits zero. It works where BIOS and firmware settings fail.

Here is how I configure it on my Debian-based storage boxes:

# 1. Install build essentials and git
sudo apt-get install build-essential git

# 2. Clone and build hd-idle
git clone https://github.com/adelolmo/hd-idle
cd hd-idle
make
sudo make install

# 3. Configure the service
# Edit /etc/default/hd-idle to set your timeouts
# -i 0 means "global idle time" (I usually disable global and set per-disk)
# -a tells it which specific disk ID to watch
# -i 900 means 900 seconds (15 minutes)

HD_IDLE_OPTS="-i 0 -a /dev/disk/by-id/wwn-0x5000cca25dcc509c -i 900 -a /dev/disk/by-id/wwn-0x5000cca25dcc509d -i 900"

Pro Tip: Always map drives by ID (`/dev/disk/by-id/`), not by label (`/dev/sda`). If you reboot and `sda` becomes `sdb`, you don’t want your spindown config applying to the wrong drive.

Solution 3: The ‘Nuclear’ Option (Tuning TXG Timeout)

Warning: I call this the nuclear option because it involves tweaking kernel parameters. This is effective, but it comes with a risk: if your power fails, you lose more data.

Remember that 5-second write flush I mentioned? If your server is just sitting there doing minor background tasks, that 5-second heartbeat keeps the drives awake. We can change that heartbeat. On my backup server backup-vault-03, which only receives data once a night, I increased the write timeout to allow the drives longer periods of silence.

We are going to change zfs_txg_timeout. By setting this to a higher value, we tell ZFS, “Keep data in RAM longer before waking up the disk.”

Setting Default Aggressive Tuning
zfs_txg_timeout 5 (seconds) 30, 60, or even 300 (seconds)

To apply this dynamically (resets on reboot):

# Set flush to 60 seconds
echo 60 > /sys/module/zfs/parameters/zfs_txg_timeout

If you combine this with a script that buffers writes to an SSD (using L2ARC or a Special VDEV for metadata), your mechanical drives can stay asleep for hours. But realize that if you set this to 60 seconds and pull the plug, you lose the last minute of data. In a production database? Never. In a home media server? Probably worth the silence.

Darian Vance - Lead Cloud Architect

Darian Vance

Lead Cloud Architect & DevOps Strategist

With over 12 years in system architecture and automation, Darian specializes in simplifying complex cloud infrastructures. An advocate for open-source solutions, he founded TechResolve to provide engineers with actionable, battle-tested troubleshooting guides and robust software alternatives.


🤖 Frequently Asked Questions

âť“ Why do ZFS drives not spin down by default?

ZFS is a Copy-on-Write filesystem that buffers writes and flushes them in Transaction Groups (TXGs) every 5 seconds by default. Additionally, it updates metadata like `atime` frequently, creating constant disk activity that prevents drives from entering standby mode.

âť“ How does `hd-idle` compare to `hdparm -S` for ZFS spindown?

`hdparm -S` is often unreliable with ZFS arrays, particularly when using SAS HBAs, as drives may ignore the command or wake immediately. `hd-idle` operates as a daemon, monitoring OS-level activity and issuing forced SCSI spindown commands, proving more effective.

âť“ What is a common implementation pitfall when configuring `hd-idle`?

A common pitfall is mapping drives by label (e.g., `/dev/sda`) instead of by ID (e.g., `/dev/disk/by-id/wwn-0x…`). Using labels can lead to incorrect spindown configurations after a reboot if drive assignments change, potentially applying settings to the wrong disk.

Leave a Reply

Discover more from TechResolve - SaaS Troubleshooting & Software Alternatives

Subscribe now to keep reading and get access to the full archive.

Continue reading