Skip to content

Research notes / Filesystem recovery

ZFS ZIL and SLOG: the boundary between logging and persistence

14 October 2026 / Primary-source synthesis / OpenZFS 2.3.4

A separate log device can help satisfy synchronous writes before a transaction group finishes. It is not a general write cache, a backup, or proof that every acknowledged byte has already reached its final place in the pool.

Three names, three responsibilities

The ZFS Intent Log (ZIL) records filesystem operations for recovery. OpenZFS maintains it per dataset, with in-memory and on-disk representations. An in-memory intent can disappear after its transaction group commits without ever needing an on-disk log record. [1]

A separate log (SLOG) changes where log blocks can be allocated. Without one, ZFS allocates the intent log from the main pool. The manual distinguishes log devices from read-cache devices; adding a SLOG does not install a general-purpose cache in front of every write. [2]

The transaction group (TXG) batches changes to persistent state. Its lifecycle has open, quiescing and syncing stages. Different groups can occupy these stages concurrently; a TXG number is an ordering identifier, not a timestamp or application transaction ID. [4]

Normal writeback is not a replay from SLOG

The pinned implementation describes two ways an intent becomes unnecessary in memory: the TXG persists it, or synchronous work commits it to the on-disk ZIL. After a crash, relevant on-disk records are replayed when the dataset is instantiated, such as at mount. During normal operation, TXG synchronization writes the accumulated in-memory state and advances the pool's committed root. [1] [4]

Hesela's inference: think of logging as an additional recovery route, not a conveyor that must reread every SLOG byte before normal writeback. Likewise, the source's five-second TXG timeout is a scheduling parameter, not a guaranteed maximum data-loss window. Progress also depends on syncing work and storage completion. [4]

Skipping SLOG is not disabling durability

OpenZFS 2.3 documented contracts, not tuning recommendations. [3]
SettingMeaningDo not infer
sync=standardHonor application synchronous requests.Every ordinary write is synchronous.
sync=alwaysMake filesystem transactions synchronous.A multi-call application update becomes atomic.
sync=disabledIgnore application synchronous requests; commit periodically.A successful sync call proves crash durability.
logbias=latencyPrefer low-latency handling, using configured log devices.Every payload must be copied to SLOG.
logbias=throughputOptimize synchronous work without configured log devices.Synchronous requests are disabled.

Changing the acknowledgment contract changes the experiment. A faster result obtained by ignoring synchronization is not evidence of a faster durable storage path. This is a comparison rule, not a recommendation to change production properties.

The overlooked case: a log entry can be a pointer

In WR_INDIRECT mode, data is written into the filesystem and the log records a block pointer. TXG commit links the block into the committed state. Other modes copy data into a log record immediately or obtain it when a later commit requires it. [6]

Do not derive current behavior solely from that explanatory comment. In OpenZFS 2.3.4, zfs_log_write() selects indirect mode for throughput bias or direct I/O, and also for sufficiently large writes without a SLOG. This is the filesystem path; it is not a universal rule for every zvol request or future release. [5]

The same distinction matters in telemetry: the source labels the zil_itx_*_bytes counters as transaction data lengths, not actual log-record sizes. A large indirect-byte count therefore does not prove that the same number of bytes was copied onto the SLOG. Compare counters with matching scope and block-device I/O. [6]

Name the failure before claiming protection

Separate log devices belong to the pool and can be mirrored; RAID-Z log vdevs are not supported. Log redundancy and data-vdev redundancy are separate configuration questions. A SLOG is not an independent copy of the pool. [2]

The implementation can fall back to waiting for TXG synchronization after a log I/O error. That fallback must not be confused with recovering an already acknowledged record whose only surviving log copy is lost before the corresponding TXG is durable. Log survival, main-pool survival and the timing of the failure must be stated separately. [1]

Historical research shows another boundary. Zhang and colleagues injected disk and memory faults into Solaris Express build 108 on a single-disk VM. They tested nine classes of on-disk blocks, and repeated individual memory fault-injection tests five times. Disk checksums detected the tested disk corruptions, while some memory corruptions escaped detection or caused crashes. [7, sections 4.2-4.3 and 5.2-5.3]

Those are controlled, historical fault-injection results, not current OpenZFS failure rates or a SLOG benchmark. Their relevance here is the distinction between preserving an acknowledged operation and ensuring its bytes were correct before persistence.

What a useful measurement must report

Record the OpenZFS version, filesystem versus zvol path, application sync calls, dataset properties, log topology, device persistence guarantees and failure being tested. Keep ordinary write latency separate from sync completion latency. Preserve errors and incomplete requests in the report.

This is an evidence checklist, not a completed hardware experiment. Related analyses explain latency measurement, NFS stable writes, database WAL and checkpoints and checksum boundaries. Filesystem recovery does not replace the application's transaction protocol.

Primary sources and limits

Primary-source synthesis of OpenZFS 2.3 documentation, pinned 2.3.4 implementation and targeted methods/results review of the FAST 2010 ZFS fault-injection study. No ZFS pool was modified and no power-cut experiment, performance benchmark or paper reproduction was performed. Implementation paths are version-specific; the historical study is not a present-day failure-rate estimate.

  1. OpenZFS 2.3.4: zil.c, log lifecycle, zil_commit and zil_replay
  2. OpenZFS 2.3: zpoolconcepts(7), Intent Log and Cache Devices
  3. OpenZFS 2.3: zfsprops(7), sync and logbias
  4. OpenZFS 2.3.4: txg.c, transaction-group lifecycle and synchronization
  5. OpenZFS 2.3.4: zfs_log.c, zfs_log_write selection of write state
  6. OpenZFS 2.3.4: zil.h, indirect and copied log records; statistics units
  7. Yupu Zhang, Abhishek Rajimwale, Andrea C. Arpaci-Dusseau and Remzi H. Arpaci-Dusseau. End-to-end Data Integrity for File Systems: A ZFS Case Study. FAST 2010, sections 4.2-4.3 and 5.2-5.3.

Sources checked 14 October 2026. Code references pin a release, not the latest version.