👍 What we like
- Significant improvement in read performance thanks to L2ARC
- Reduced load on mechanical drives by using multi-level caches
- Flexible configuration tailored to different workloads (read/write)
- Compatibility with TrueNAS and Proxmox for easy integration
👎 What to watch
- SSDs for cache must be high-quality to avoid rapid saturation
- Advanced configuration requires command-line and system administration skills
- Regular monitoring is essential to maintain performance
- Risk of data loss if ZIL fails without supercapacitor backup
🏆 Our picks
Affiliate links · same price for youSabrent Rocket 4 Plus 8 To
Amazon · price and availability on the listing
See all our recommended gear in the shop.
📑 Contents ▾
ZFS is an open-source file system that excels in managing multi-level caches. The first level, ARC (Adaptive Replacement Cache), uses your system’s RAM to speed up the most frequent reads and writes. When ARC is saturated, ZFS can use a second-level cache, L2ARC, which stores data on a dedicated SSD. This cache is particularly effective for frequent random reads, as it avoids accessing slow mechanical drives. Finally, the ZIL (ZFS Intent Log) accelerates synchronous writes by temporarily storing them on non-volatile media. This guide explains how to configure these caches to maximize the performance of your NAS running TrueNAS or Proxmox. You’ll learn how to optimize ARC, add an L2ARC for reads, and configure a ZIL for synchronous writes. These optimizations can deliver performance close to an all-SSD system while using mechanical drives for primary storage, reducing costs and improving reliability. The configuration can be adapted to the size of your active working set, typically between 10% and 20% of the total ZFS pool capacity.
Prerequisites
To configure a ZFS cache on your NAS, you will need:
- A TrueNAS or Proxmox system already installed with ZFS
- A compatible SSD (M.2 or 2.5” format) for the L2ARC cache
- A compatible SSD for the ZIL (ideally SLC or backed by supercapacitors)
- The latest stable version of TrueNAS or Proxmox
- Root access to the system for terminal commands
- An existing ZFS dataset
- Knowledge of your approximate active working set size
Step-by-step installation
Step 1: Estimate the active working set size
A ZFS cache is only effective if its size matches your working set. An undersized cache will be useless, while an oversized one will waste SSD capacity.
To estimate your working set, use:
zpool iostat -v
This command shows usage statistics for each vdev. Note the read and write values on your mechanical drives. In practice, an active working set is about 20% of the total ZFS pool capacity. For a more precise estimate, analyze file usage statistics:
zfs list -t all -o name,used,referenced
Check the referenced column to see the active size of your datasets. If you’re using TrueNAS, review usage reports in the web interface under System > Analytics > Reporting.
Verification: If you see that most of your data is concentrated in a few datasets, this confirms your working set is well below the pool’s total size. Proceed to the next step.
Step 2: Prepare the SSD for L2ARC
L2ARC is a read cache that stores the most recently and frequently accessed data. It doesn’t require a high-end SSD, but it should be fast enough to improve access times over your HDDs.
If your SSD is M.2 format, ensure it’s inserted into a compatible PCIe 4.0 slot. For a 2.5” SSD, verify it’s connected to a free SATA port.
Identify the SSD to be used for L2ARC. Do not format or mount it: ZFS uses it directly, and all data on it will be erased.
# Identify the SSD device
lsblk
ls -l /dev/disk/by-id/
Verification: In the
lsblkoutput, the SSD (for example/dev/sdX) must have no mountpoint and must not belong to any pool (zpool status).
Step 3: Configure ARC (Adaptive Replacement Cache)
ARC is ZFS’s first-level cache, using system RAM. It’s already configured by default, but you can optimize its parameters for your hardware.
For TrueNAS, adjust parameters in System > Tunables:
# Valeur en octets (TrueNAS SCALE : à appliquer via un script d'initialisation)
echo 13421772800 > /sys/module/zfs/parameters/zfs_arc_max
For Proxmox, edit /etc/modprobe.d/zfs.conf:
# Add these lines to optimize ARC
# Maximum ARC size, in bytes
options zfs zfs_arc_max=13421772800
# Regenerate the initramfs, then reboot to apply
update-initramfs -u -k all
reboot
Verification: Check with
cat /sys/module/zfs/parameters/zfs_arc_maxandgrep c_max /proc/spl/kstat/zfs/arcstatsthatc_maxmatches your configuration.
Step 4: Configure L2ARC (SSD read cache)
L2ARC is a read cache using a dedicated SSD. It’s particularly effective for frequent random reads.
For TrueNAS, add the SSD as cache in Storage > Pools > Add Cache Device. Select the target pool and the SSD to use as cache (L2ARC).
For Proxmox, use the following command to add the cache:
# Add L2ARC cache to your ZFS pool
zpool add <poolname> cache /dev/sdX
# Verify cache configuration
zpool status <poolname>
Verification: Run
zpool iostat -v 2to see L2ARC activity. If read values increase, the cache is working correctly.
Step 5: Configure ZIL (synchronous write cache)
ZIL accelerates synchronous writes by temporarily storing them on non-volatile media. It’s particularly important for services like NFS or frequent synchronous writes.
For TrueNAS, add the SSD as log in Storage > Pools > Add Log Device. Select the target pool and the second SSD to use as log (SLOG).
For Proxmox, use the following command to add ZIL:
# Add ZIL to your ZFS pool
zpool add <poolname> log /dev/sdY
# Verify ZIL configuration
zpool status <poolname>
Verification: Run
zpool iostat -v 2and monitorwritevalues on ZIL. If they increase, the cache is working correctly.
Step 6: Optimize cache parameters
After configuring ARC, L2ARC, and ZIL, you can optimize cache parameters to maximize performance.
For TrueNAS, adjust parameters in System > Tunables:
# Valeurs en octets (TrueNAS SCALE : à appliquer via un script d'initialisation)
echo 104857600 > /sys/module/zfs/parameters/l2arc_write_max
echo 2 > /sys/module/zfs/parameters/l2arc_headroom
For Proxmox, edit /etc/modprobe.d/zfs.conf:
# Add these lines to optimize L2ARC
options zfs l2arc_write_max=104857600
options zfs l2arc_write_boost=104857600
options zfs l2arc_headroom=2
# Regenerate the initramfs, then reboot to apply
update-initramfs -u -k all
reboot
Verification: Run
cat /sys/module/zfs/parameters/l2arc_write_maxto verify cache parameters. Values should match your configuration.
Then regularly monitor your cache activity to make sure it works as expected and is not saturated. For TrueNAS, use the usage reports under System > Analytics > Reporting. For Proxmox, run:
# Display cache statistics
arc_summary
If the hit ratio shown by arc_summary is high (for example > 80%), your cache is effective. If it is low, you may need to adjust the cache size or usage parameters.
Verification checks
To verify your ZFS cache is correctly configured and functioning, run the following commands in order:
# Check ZFS pool status
zpool status <poolname>
# Display ARC statistics
cat /proc/spl/kstat/zfs/arcstats | grep -E "c_max|c_min|hits"
# Display L2ARC statistics
zpool iostat -v 2
Expected results:
- The
zpool statuscommand should show SSD disks configured ascacheandlogin the vdev list. - The
c_maxandc_minvalues inarcstatsshould match your configuration. - The hit ratio shown by
arc_summaryshould be high (for example > 80%) if your cache is effective. - L2ARC should show non-zero read activity in
zpool iostat.
Security and best practices
Security for your ZFS cache is critical to prevent data loss or performance issues. For the ZIL, prefer SLC SSDs or solutions backed by supercapacitors if available, as they ensure persistence of synchronous writes during power outages. Standard TLC or MLC SSDs are not recommended for ZIL, as they may lose data during power failures. For L2ARC, use a high-quality SSD with sufficient endurance to avoid premature cache saturation. Finally, regularly monitor SSD health using smartctl -a /dev/sdX or zpool status. If an SSD shows signs of failure, replace it immediately to prevent cache issues.
Troubleshooting common errors
Cause: The SSD was not added to the pool as a cache vdev, or the cache has not warmed up yet.
Fix: Verify with zpool status <poolname> that the SSD is listed under cache (it must not be formatted or mounted). L2ARC fills gradually as data is read: give it time to warm up.
Symptom: ARC saturating too quickly
Cause: The size of your active working set exceeds ARC capacity.
Fix: Increase ARC size by adding more RAM or increasing the zfs_arc_max parameter in /etc/modprobe.d/zfs.conf. If the issue persists, reduce working set size or limit random access.
Symptom: ZIL showing no activity
Cause: The ZIL is configured on an inappropriate disk or synchronous writes aren’t being used.
Fix: Verify the SSD is properly configured as log with zpool status. If your workload doesn’t include synchronous writes, ZIL won’t be utilized. To force synchronous writes, use zfs set sync=always <poolname>/<dataset>.
Symptom: System becoming slow after adding cache
Cause: The SSD cache is saturated or the SSD is too slow.
Fix: Check cache status with arc_summary or zpool iostat -v. If saturated, increase SSD size or remove it from the pool with zpool remove <poolname> /dev/sdX. If the SSD is too slow, replace it with a higher-performance model or verify its connection.
FAQ
How to choose the L2ARC size?
The L2ARC size depends on your active working set. In practice, an L2ARC cache of 10% to 20% of the total ZFS pool size is often sufficient for typical workloads. For a 10TB pool, a 2TB SSD is a common size. If you’re using TrueNAS or Proxmox, review usage statistics to adjust the size. An excessively large cache consumes RAM for L2ARC headers at the expense of ARC, which can reduce performance.
What’s the difference between L2ARC and ZIL?
L2ARC is a read cache that speeds up access to data already stored on HDDs. ZIL is a write cache that temporarily stores synchronous writes before committing them to the pool. ZIL is critical for performance when using NFS or frequent synchronous writes. In practice, ZIL should be on non-volatile media to prevent data loss during power outages.
Can the same SSD be used for both L2ARC and ZIL?
Yes, it’s possible, but not recommended. L2ARC and ZIL have different roles and distinct performance requirements. Using separate SSDs allows optimizing performance for each cache. If you only have one SSD, configure it as L2ARC and use a supercapacitor-backed ZIL to maximize security.
How to clean the L2ARC cache?
To clear the L2ARC cache, remove the cache device with zpool remove <poolname> /dev/sdX, then add it back with zpool add <poolname> cache /dev/sdX. Since L2ARC is persistent by default (l2arc_rebuild_enabled), a simple reboot does not clear it. Finally, verify cache status with zpool status to confirm the cache has been cleaned.