ZFS has earned its reputation as one of the most robust and advanced file systems in the world. It powers everything from home NAS builds and media servers to enterprise storage arrays and virtualization clusters. Its unmatched data integrity, snapshotting, and self-healing capabilities make it a favorite among power users and system administrators alike. Yet one question continues to appear in every ZFS forum, Reddit thread, and Discord server: “How do I make ZFS faster?”
The usual answers involve three mysterious acronyms—ARC, L2ARC, and SLOG. These caching layers promise dramatic performance improvements when paired with SSDs, but they also generate confusion, myths, and expensive mistakes. Many users add a fast NVMe drive as L2ARC or SLOG, only to see little improvement or, in some cases, worse performance.
This article provides a complete, practical, and technically accurate guide to tuning ZFS performance using ARC, L2ARC, and SLOG. You will learn what each cache layer actually does, how it behaves in real systems, how to size and tune it correctly, and what real-world benchmarks tell us about performance gains. Most importantly, you will learn when not to use these cache devices—because in ZFS, more hardware does not always equal more speed.
Understanding ZFS Caching at a High Level
ZFS uses a multi-layer caching architecture designed to optimize both read and write performance while preserving data integrity. These layers operate at different points in the I/O pipeline and serve very different purposes:
ARC is the primary in-memory read cache.
L2ARC is an optional secondary read cache on fast storage, typically SSDs.
SLOG is a dedicated device for accelerating synchronous writes.
Together, they form a tiered performance system that prioritizes data safety first and speed second. Unlike traditional RAID controllers that rely on volatile write-back caches, ZFS insists on correctness before performance. This design philosophy is the reason ZFS behaves differently from file systems many users are familiar with.
To tune ZFS effectively, you must first understand how each component works in isolation—and how they interact under real workloads.
ARC: The Heart of ZFS Performance
The Adaptive Replacement Cache (ARC) is the single most important performance component in any ZFS system. It is a RAM-based cache that stores frequently accessed data blocks and metadata. Every read operation first checks the ARC before touching disk. If the requested data is already in memory, it is returned almost instantly.
How ARC Actually Works
Unlike a simple least-recently-used cache, ARC uses two balanced lists:
MRU (Most Recently Used) for newly accessed data
MFU (Most Frequently Used) for repeatedly accessed data
By dynamically shifting memory between these two lists, ARC adapts to both streaming workloads and random access patterns. It also prioritizes metadata such as directory structures, block pointers, and file records. This is especially beneficial for virtualization and database workloads, where metadata access is heavy.
Why RAM Matters More Than SSD for ZFS
A common ZFS rule of thumb is “RAM is king.” While modern NVMe SSDs are extremely fast, they are still orders of magnitude slower than DDR memory and have much higher latency. If your working dataset fits into ARC, your storage can feel as fast as local memory.
For most systems, the biggest single performance upgrade is not adding L2ARC or SLOG—it is simply adding more RAM. Many disappointing “ZFS is slow” reports can be traced directly to insufficient ARC capacity.
ARC Sizing in Practice
ARC dynamically grows and shrinks based on system memory pressure. On most systems, ZFS will attempt to use up to 50–75 percent of available RAM for ARC, depending on the platform and configuration. However, this behavior varies:
On FreeBSD-based systems like TrueNAS CORE, ARC has traditionally dominated memory.
On Linux-based systems like TrueNAS SCALE and Proxmox, ARC competes with the kernel page cache.
For home servers, practical guidance is simple:
16 GB RAM: Suitable only for light file-server workloads.
32 GB RAM: Comfortable for mixed file serving and light virtualization.
64 GB RAM and above: Ideal for heavy VM and database workloads.
If your ARC hit ratio is consistently below 80 percent on active datasets, you are likely RAM-bound.
L2ARC: The Most Misunderstood SSD Cache
The Level 2 ARC (L2ARC) is a secondary read cache that extends ARC onto a fast storage device, usually an SSD or NVMe drive. When ARC evicts data from memory, some of it may be written into L2ARC for possible future reuse.
This sounds straightforward, yet L2ARC is responsible for more wasted money in ZFS builds than almost any other feature.
What L2ARC Does and Does Not Do
L2ARC is strictly a read cache. It never accelerates writes. It does not store dirty data awaiting disk commit. It only serves read requests that missed ARC.
More importantly, L2ARC does not work independently. Every L2ARC entry must still be indexed by ARC metadata in RAM. This means that using L2ARC consumes memory in addition to consuming SSD space.
Why L2ARC Often Hurts Small Systems
On a system with limited RAM, adding L2ARC can actually reduce performance. The RAM used to index L2ARC could have been used to hold actual hot data directly in ARC. The result is more cache misses, more SSD reads, and higher latency.
For most home users with less than 64 GB of RAM, L2ARC provides little to no benefit. It becomes meaningful only when:
The active dataset is far larger than available RAM.
The workload repeatedly accesses the same data over time.
There is sufficient memory to index the L2ARC without starving ARC.
Virtual machine images, large software repositories, and frequently accessed project directories are common examples where L2ARC can help.
L2ARC Warm-Up Behavior
Unlike ARC, L2ARC is empty at boot. It must be repopulated over time as data cycles through ARC. On large datasets, this warm-up period can take hours or even days. During this time, performance behaves as if L2ARC does not exist.
This behavior surprises many users who expect instant performance improvements after adding an SSD cache device.
SLOG: The Guardian of Synchronous Writes
The Separate Intent Log (SLOG) is not a cache in the traditional sense. It is a dedicated device that accelerates synchronous writes by temporarily absorbing them before they are later flushed into the main pool.
To understand SLOG, you must understand how ZFS handles writes.
ZIL and SLOG Explained Clearly
ZFS always writes data to the main pool in transaction groups (TXGs) every few seconds. For asynchronous writes, the system acknowledges the write before it is physically committed. For synchronous writes, ZFS must guarantee that the data is safely stored on stable storage before acknowledging completion.
By default, synchronous writes are stored in the on-pool ZFS Intent Log (ZIL). This can be slow, especially on rotating disks or parity-based vdevs. A dedicated SLOG device provides a fast, low-latency place for these writes, dramatically reducing write latency for sync workloads.
What SLOG Accelerates—and What It Does Not
SLOG improves latency, not throughput. It does not increase sequential write speed. It only shortens the time applications wait for synchronous write acknowledgments.
Workloads that benefit include:
Virtual machines with sync enabled
Databases
NFS workloads with sync writes
Applications using fsync heavily
SLOG provides almost no benefit for:
Media streaming
Large file copies over SMB with sync disabled
Backup targets using async writes
The Absolute Importance of Power-Loss Protection
Because SLOG holds data that has not yet been written to the main pool, it must survive power loss. Consumer SSDs typically lack full power-loss protection and can lose in-flight writes during outages. This can lead to silent data corruption, broken virtual machines, or database corruption.
A proper SLOG device should have:
Capacitors for power-loss protection
Low write latency
High endurance
Consistent performance under sustained small writes
Enterprise-grade SSDs or specialized NVMe devices are strongly recommended.
Benchmarking Methodology: How ZFS Cache Performance Should Be Measured
Before discussing results, it is important to understand how real benchmarks are performed. Synthetic benchmarks can be misleading if they do not reflect real workloads.
A credible ZFS caching benchmark should define:
Hardware platform (CPU, RAM, storage topology)
Pool layout and vdev types
ARC size and behavior
Dataset properties (recordsize, compression, sync)
Workload type (random vs sequential, sync vs async)
Typical Test Platform
A common mid-range test system might include:
8- to 16-core CPU
64–128 GB DDR4/DDR5 RAM
ZFS pool of 6–8 HDDs in RAIDZ2
1–2 NVMe SSDs for cache
10 GbE networking
Testing is typically performed with tools like fio, ioping, and real VM workloads.
Real-World Performance Observations
ARC-Only Baseline
With sufficient RAM, ARC alone often delivers outstanding performance. On a system with 128 GB of RAM serving a 2 TB active dataset, ARC hit ratios frequently exceed 90 percent. Random read IOPS can reach hundreds of thousands, far beyond the raw disk capability.
In these scenarios, adding L2ARC produces little additional benefit because most reads are already satisfied from memory.
L2ARC Impact on Large Working Sets
On a system with 64 GB of RAM serving a 10 TB dataset of VM images, L2ARC can provide measurable gains once warmed:
Random read latency can drop by 40–70 percent.
Read IOPS may increase by 2–5× under VM workloads.
Boot storms in VDI-style environments benefit significantly.
However, in file-server workloads with mostly sequential access, L2ARC impact is often negligible.
SLOG Impact on Sync-Heavy Workloads
Without SLOG, sync write latency on HDD-based pools can exceed 10–20 milliseconds. With a proper NVMe SLOG device, this can drop below 1 millisecond.
Virtual machine performance improves dramatically:
Database commit latency drops sharply.
VM responsiveness under disk stress improves.
NFS workloads become far more consistent.
On pure SMB media servers, SLOG shows almost no measurable benefit because sync writes are rare.
Tuning Parameters That Actually Matter
ZFS exposes many tunable parameters, but only a few are commonly useful for performance tuning in production systems.
ARC Size Control
On Linux, you can set minimum and maximum ARC size using kernel module parameters. This can be useful to prevent ZFS from starving other workloads such as hypervisors or containers.
However, in most systems, automatic ARC sizing works well and should not be overridden unless there is a clear resource conflict.
primarycache and secondarycache
These dataset properties control what is cached in ARC and L2ARC:
primarycache=all caches data and metadata.
primarycache=metadata caches only metadata.
secondarycache=all or metadata controls L2ARC behavior.
For large sequential datasets like backups, caching only metadata prevents ARC pollution and preserves memory for hot data.
sync and logbias
Setting sync=always forces synchronous writes, which increases data safety but reduces performance unless a SLOG device is present. Setting logbias=latency prioritizes low-latency writes to SLOG for certain datasets like databases.
These properties must be used carefully. Improper use can easily reduce both performance and reliability.
L2ARC Write Throttling
Modern OpenZFS allows control over how aggressively L2ARC is populated. Over-aggressive population can increase SSD wear without improving hit rates. In most cases, default values are appropriate.
Platform Differences: FreeBSD vs Linux ZFS
While OpenZFS aims for feature parity, ARC behavior differs subtly between platforms.
On FreeBSD-based systems such as TrueNAS CORE:
ARC dominates memory use.
Memory behavior is predictable and tightly integrated with ZFS.
On Linux-based systems such as Proxmox and TrueNAS SCALE:
ARC competes with the Linux page cache.
Memory pressure from containers and VMs can shrink ARC faster.
Manual tuning is sometimes required for stability.
These differences explain why identical hardware can exhibit different performance depending on the operating system.
Real-World Use Cases and Cache Strategy
Home Media Server
Typical workload: Large sequential reads, minimal sync writes.
Best strategy:
Maximize ARC with sufficient RAM.
Avoid SLOG.
L2ARC usually unnecessary unless the library is massive and frequently browsed.
Virtualization Host
Typical workload: Random reads and sync writes.
Best strategy:
Large ARC.
High-quality SLOG with PLP.
Optional L2ARC if dataset exceeds RAM.
Backup Server
Typical workload: Large async writes.
Best strategy:
ARC tuned for metadata.
No SLOG required.
L2ARC rarely useful.
Database Server
Typical workload: Heavy sync writes and random reads.
Best strategy:
High-performance SLOG.
Large ARC.
Carefully measured L2ARC if dataset exceeds memory.
Reliability, Risk, and Data Safety
One of the most dangerous misconceptions in ZFS tuning is that cache devices can compensate for weak pool design. They cannot.
L2ARC is disposable. If it fails, only cache data is lost, not pool integrity. SLOG is not disposable. If it fails during power loss and lacks PLP, recently acknowledged synchronous writes may be lost permanently.
Cache does not replace:
Redundant vdevs
Scrubbing
SMART monitoring
Proper backups
Removing L2ARC or SLOG devices requires care. SLOG removal should only be done when the pool is idle to avoid losing in-flight sync writes.
Cost-to-Performance Reality
From a value perspective, the performance hierarchy is clear:
More RAM yields the biggest and most reliable performance gains.
Better pool design (more vdevs, mirrors instead of RAIDZ) often beats caching.
SLOG provides dramatic gains only for specific workloads.
L2ARC is situational and often overused.
For many users, the money spent on a large NVMe L2ARC device would be better spent doubling system RAM.
Future Trends in ZFS Caching
As storage technology evolves, ZFS caching continues to improve:
NVMe devices with millions of IOPS reduce L2ARC latency to near-memory speeds.
Persistent memory technologies blur the line between ARC and L2ARC.
25 GbE and 100 GbE networking make cache efficiency even more critical.
OpenZFS continues to refine ARC eviction and prefetch algorithms.
These trends suggest that intelligent memory management will remain central to ZFS performance for years to come.
Practical Checklist Before Adding ZFS Cache Devices
Before purchasing any SSD for cache purposes, consider the following:
Is ARC frequently exceeding 80–90 percent hit rate?
Is the system genuinely limited by storage latency or by CPU/network?
Are workloads dominated by synchronous writes?
Is there enough RAM to support L2ARC indexing?
Does the intended SLOG device have verified power-loss protection?
Have baseline benchmarks already identified the true bottleneck?
If you cannot answer these questions clearly, caching may not improve your system.
ZFS performance tuning is both powerful and perilous. ARC, L2ARC, and SLOG offer extraordinary capabilities when used correctly, but they demand architectural understanding and careful measurement. Blindly adding SSDs in the hope of fixing “slow ZFS” often leads to disappointment or unnecessary cost.
In most cases, RAM is the most effective performance upgrade. L2ARC becomes valuable only in large, read-heavy environments with sufficient memory. SLOG is indispensable for sync-heavy workloads like virtualization and databases but completely unnecessary for simple file serving.
ZFS rewards thoughtful design. When cache layers are chosen based on real workload analysis rather than forum folklore, the result is a storage system that combines enterprise-grade data integrity with exceptional real-world performance.






