Skip to content

Instantly share code, notes, and snippets.

@jjo
Last active September 4, 2025 15:10
Show Gist options
  • Save jjo/3e6416cf12ddc4021d17c3fda7aec8ba to your computer and use it in GitHub Desktop.
Save jjo/3e6416cf12ddc4021d17c3fda7aec8ba to your computer and use it in GitHub Desktop.
#!/bin/bash
# ZFS Performance Tuning Script
# Run with appropriate privileges (sudo/root)
set -e # Exit on any error
# Check if ZFS module is loaded
if ! lsmod | grep -q zfs; then
echo "Error: ZFS module not loaded"
exit 1
fi
# Get total system memory in bytes for ARC calculation
TOTAL_MEM=$(awk '/MemTotal:/ {print $2 * 1024}' /proc/meminfo)
# Set ARC to 50% of total memory (adjust as needed)
ARC_MAX=$((TOTAL_MEM / 2))
echo "Applying ZFS tuning parameters..."
# Transaction Group timeout (default: 5s)
# 60s reduces write amplification but increases sync write latency
# Consider 10-30s for better balance
echo "Setting TXG timeout to 30 seconds..."
echo 30 > /sys/module/zfs/parameters/zfs_txg_timeout
# ARC maximum size (adaptive based on system memory)
echo "Setting ARC max to $(($ARC_MAX / 1024 / 1024))MB..."
echo $ARC_MAX > /sys/module/zfs/parameters/zfs_arc_max
# Async block limits for better throughput
echo "Setting async block limits..."
echo 50000 > /sys/module/zfs/parameters/zfs_async_block_max_blocks
# Explicitly set sync queue depths (safer than wildcards)
echo "Setting sync I/O queue depths..."
for param in zfs_vdev_sync_read_min_active zfs_vdev_sync_read_max_active \
zfs_vdev_sync_write_min_active zfs_vdev_sync_write_max_active; do
if [ -f "/sys/module/zfs/parameters/$param" ]; then
echo 2 > "/sys/module/zfs/parameters/$param"
echo " $param = 2"
else
echo " Warning: $param not found"
fi
done
# Additional performance tuning parameters
echo "Applying additional tuning..."
# Increase async write limits for better throughput
echo 8 > /sys/module/zfs/parameters/zfs_vdev_async_write_min_active
echo 32 > /sys/module/zfs/parameters/zfs_vdev_async_write_max_active
# Increase async read limits
echo 8 > /sys/module/zfs/parameters/zfs_vdev_async_read_min_active
echo 32 > /sys/module/zfs/parameters/zfs_vdev_async_read_max_active
# Scrub I/O limits (lower priority background operations)
echo 1 > /sys/module/zfs/parameters/zfs_vdev_scrub_min_active
echo 8 > /sys/module/zfs/parameters/zfs_vdev_scrub_max_active
# L2ARC tuning (if you have L2ARC devices)
echo 1 > /sys/module/zfs/parameters/l2arc_noprefetch # Disable L2ARC prefetch
echo $((128 * 1024 * 1024)) > /sys/module/zfs/parameters/l2arc_write_max # 128MB/s write limit
echo "ZFS tuning completed successfully!"
# Display current values for verification
echo -e "\nCurrent ZFS parameter values:"
echo "TXG timeout: $(cat /sys/module/zfs/parameters/zfs_txg_timeout)s"
echo "ARC max: $(cat /sys/module/zfs/parameters/zfs_arc_max | numfmt --to=iec)"
echo "Async blocks: $(cat /sys/module/zfs/parameters/zfs_async_block_max_blocks)"
set -x
zfs set sync=disabled zpool1/var_lib_docker
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment