Skip to main content

Ubuntu 24.04 ZFS: Post-Install Optimization

ubuntu zfs configuration performance

ZFS optimization, kernel tuning, and system monitoring configuration for Ubuntu 24.04.

Continues from installation guide.

Prerequisites: System installed, rebooted, and accessible with sudo.

Install Additional System Packages

Essential utilities for system management, monitoring, and remote access.

sudo apt update
sudo apt install --yes \
  fwupd \
  htop \
  linux-tools-generic-hwe-24.04 \
  openssh-server \
  tmux \
  ubuntu-server-minimal \
  ubuntu-standard \
  vim

Upgrade to Latest OpenZFS

Install latest OpenZFS version from arter97 PPA for improved features and performance.

sudo add-apt-repository ppa:arter97/zfs
sudo apt update
sudo apt install --yes zfs-dkms
sudo reboot

Verify and upgrade pool:

zfs --version
zpool version

sudo zpool set compatibility=off zroot
sudo zpool upgrade zroot
zpool status zroot
zpool get all zroot | grep feature

ZFS Module Parameters

Configure ZFS kernel module settings for optimal memory usage, caching, and I/O performance.

Values optimized for 64GB RAM with large files workload. Scale zfs_arc_max to ~75% of total RAM, zfs_arc_min to ~12-15%.

sudo tee /etc/modprobe.d/zfs.conf > /dev/null << 'EOF'
# ARC: 48GB max, 8GB min
options zfs zfs_arc_max=51539607552
options zfs zfs_arc_min=8589934592

# L2ARC for M.2 cache
options zfs l2arc_write_max=268435456
options zfs l2arc_write_boost=536870912
options zfs l2arc_headroom=4
options zfs l2arc_feed_again=1
options zfs l2arc_noprefetch=0

# Prefetch
options zfs zfs_prefetch_disable=0
options zfs zfs_txg_timeout=5
options zfs metaslab_preload_enabled=1

# Write performance
options zfs zfs_dirty_data_max=17179869184
options zfs zfs_dirty_data_max_percent=50
options zfs zfs_dirty_data_sync_percent=20

# I/O scheduling
options zfs zfs_vdev_async_read_max_active=4
options zfs zfs_vdev_async_write_max_active=4
options zfs zfs_vdev_sync_read_max_active=10
options zfs zfs_vdev_sync_write_max_active=10
options zfs zfs_vdev_scrub_max_active=2

# I/O aggregation
options zfs zfs_vdev_read_gap_limit=32768
options zfs zfs_vdev_aggregation_limit=1048576
options zfs zfs_vdev_write_gap_limit=32768

# Record size
options zfs zfs_max_recordsize=1048576
EOF

Apply changes & reboot:

sudo update-initramfs -u
sudo reboot

System Kernel Parameters

Configure sysctl parameters to optimize system performance. Memory settings minimize swap usage and control dirty page writeback to work efficiently with ZFS’s ARC cache. Network parameters increase buffer sizes and enable fair queuing for better throughput. TCP settings enable BBR congestion control, TCP Fast Open, and optimize keepalive timers for modern networks. Routing configuration enables IPv4/IPv6 forwarding and disables privacy extensions for stable addressing.

Memory and VM Settings

sudo tee /etc/sysctl.d/10-memory-vm.conf > /dev/null << 'EOF'
vm.swappiness=0
vm.page-cluster=0
vm.vfs_cache_pressure=50
vm.dirty_background_ratio=5
vm.dirty_ratio=10
vm.dirty_expire_centisecs=6000
vm.min_free_kbytes=262144
EOF

Network Settings

sudo tee /etc/sysctl.d/20-network-core.conf > /dev/null << 'EOF'
net.core.rmem_max=67108864
net.core.wmem_max=67108864
net.core.rmem_default=1048576
net.core.wmem_default=1048576
net.core.netdev_max_backlog=4096
net.core.default_qdisc=fq
EOF

TCP Settings

sudo tee /etc/sysctl.d/30-network-tcp.conf > /dev/null << 'EOF'
net.ipv4.tcp_rmem=4096 131072 67108864
net.ipv4.tcp_wmem=4096 65536 67108864
net.ipv6.tcp_rmem=4096 131072 67108864
net.ipv6.tcp_wmem=4096 65536 67108864
net.ipv4.tcp_congestion_control=bbr
net.ipv4.tcp_no_metrics_save=1
net.ipv4.tcp_slow_start_after_idle=0
net.ipv4.tcp_fastopen=3
net.ipv4.tcp_mtu_probing=1
net.ipv4.tcp_fin_timeout=15
net.ipv4.tcp_keepalive_time=600
net.ipv4.tcp_keepalive_intvl=30
net.ipv4.tcp_keepalive_probes=3
net.ipv6.neigh.default.gc_thresh1 = 1024
net.ipv6.neigh.default.gc_thresh2 = 2048
net.ipv6.neigh.default.gc_thresh3 = 4096
EOF

Routing Settings

sudo tee /etc/sysctl.d/40-network-routing.conf > /dev/null << 'EOF'
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.all.use_tempaddr=0
net.ipv6.conf.default.use_tempaddr=0
EOF

sudo sysctl --system

Storage I/O Scheduler Optimization

Configure optimal I/O schedulers and queue settings for SSDs, HDDs, and NVMe drives.

sudo tee /etc/udev/rules.d/10-storage-scheduler.rules > /dev/null << 'EOF'
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="mq-deadline"
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="0", ATTR{queue/nr_requests}="64"
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="0", ATTR{queue/read_ahead_kb}="128"
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="0", ATTR{queue/add_random}="0"

ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="mq-deadline"
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", ATTR{queue/nr_requests}="128"
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", ATTR{queue/read_ahead_kb}="4096"
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", ATTR{queue/add_random}="1"

ACTION=="add|change", KERNEL=="nvme[0-9]*n[0-9]*", ATTR{queue/scheduler}="none"
ACTION=="add|change", KERNEL=="nvme[0-9]*n[0-9]*", ATTR{queue/nr_requests}="32"
ACTION=="add|change", KERNEL=="nvme[0-9]*n[0-9]*", ATTR{queue/read_ahead_kb}="128"
ACTION=="add|change", KERNEL=="nvme[0-9]*n[0-9]*", ATTR{queue/add_random}="0"
EOF

sudo udevadm control --reload-rules
sudo udevadm trigger
sudo reboot

Email Configuration for System Notifications

Set up SMTP email delivery for system alerts from ZFS, SMART, and unattended-upgrades.

Install and Configure

sudo apt install msmtp msmtp-mta mailutils

Edit /etc/msmtprc:

defaults
auth           on
tls            on
tls_starttls   off
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        /var/log/msmtp.log

account        smtp
host           smtp.example.com
port           465
from           server@example.com
user           username
password       password

account default : smtp

Set permissions:

sudo chmod 644 /etc/msmtprc
sudo chown root:root /etc/msmtprc
sudo touch /var/log/msmtp.log
sudo chmod 666 /var/log/msmtp.log

Edit /etc/mail.rc:

set sendmail="/usr/bin/msmtp -t"

Send Test Email

echo "Test email from $(hostname)" | mail -s "Test: msmtp configuration" you@example.com
sudo tail -f /var/log/msmtp.log

Automatic Security Updates

Enable automatic installation of security updates with email notifications.

Install and Configure

sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

Edit /etc/apt/apt.conf.d/50unattended-upgrades:

Unattended-Upgrade::Allowed-Origins {
};

Unattended-Upgrade::Origins-Pattern {
  "origin=*";
};

Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";

Unattended-Upgrade::Sender "server@example.com";
Unattended-Upgrade::Mail "you@example.com";

Edit /etc/apt/apt.conf.d/20auto-upgrades:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

Enable Services

sudo systemctl enable unattended-upgrades
sudo systemctl start unattended-upgrades
sudo systemctl enable apt-daily-upgrade.timer
sudo systemctl start apt-daily-upgrade.timer
sudo unattended-upgrades --dry-run --debug
sudo systemctl status unattended-upgrades

Drive Health Monitoring with SMART

Configure automated drive health monitoring and testing with SMART email alerts.

Install and Configure

sudo apt install --yes nvme-cli smartmontools
sudo /usr/sbin/update-smart-drivedb

Edit /etc/smartd.conf:

DEVICESCAN -a -o on -S on -n standby,q -s (S/../.././02|L/../../6/03) -m you@example.com

DEVICESCAN -d sat -W 4,40,55
DEVICESCAN -d nvme -W 4,50,70

Configuration breakdown:

  • -a: Monitor all SMART attributes and report failures
  • -o on: Enable automatic offline testing (runs background tests when idle)
  • -S on: Enable SMART attribute autosave (preserves attribute history across power cycles)
  • -n standby,q: Skip checks if drive is in standby/sleep mode to avoid unnecessary wake-ups
  • -s (S/../.././02|L/../../6/03): Test schedule using cron-like syntax
    • S/../.././02: Short self-test daily at 2:00 AM
    • L/../../6/03: Long self-test weekly on Saturday (day 6) at 3:00 AM
  • -m you@example.com: Send email alerts for SMART failures and test results
  • -d sat: Specify SATA device type for proper SMART command interpretation
  • -d nvme: Specify NVMe device type for NVMe-specific health monitoring
  • -W 4,40,55: Temperature monitoring with difference, warning, and critical thresholds
    • 4: Alert if temperature changes by 4°C or more
    • 40°C (SATA) / 50°C (NVMe): Warning threshold
    • 55°C (SATA) / 70°C (NVMe): Critical threshold

Enable Service

sudo smartd -d -q onecheck
sudo systemctl enable smartd
sudo systemctl start smartd
sudo systemctl status smartd