A SLOG (Separate Intent Log) device is usually the smallest, fastest SSD in the box, and it is almost always the first one to die. Every synchronous write in the pool, from every dataset and every application, lands on this one device before the application gets its acknowledgment. That concentration is the point of a SLOG, and it is also why the device burns through write endurance far faster than the data vdevs around it.
ZFS will not warn you. There is no ZFS-level kstat that reports SLOG write volume or remaining endurance. The pool stays ONLINE, zpool status -x reports healthy, and the SSD’s wear counter climbs silently until the device hits its endurance limit. The failure mode is abrupt, and your sync-heavy workloads (NFS, databases, anything calling fsync) find out at the worst possible time.
This article covers why SLOG wear is concentrated, why ZFS cannot show it to you, how to monitor it at the device level, what actually happens when the device fails, and a replacement policy that keeps you ahead of the wear curve.
Why the SLOG absorbs so much write traffic
Every synchronous write (O_SYNC, fsync, NFS, database commit) must be recorded in the ZFS Intent Log before ZFS acknowledges it. Without a SLOG, the ZIL lives on the pool’s data vdevs and sync write latency is pool-speed. Adding a SLOG moves the ZIL onto a dedicated fast device, and sync write latency becomes SLOG-speed. That is the performance win.
The cost is write concentration:
- Async writes accumulate in RAM and flush to the pool in transaction groups, spread across all data vdevs.
- Sync writes bypass that path. Each one is written to the ZIL immediately, which means each one is a write to the SLOG device.
- On a pool serving NFS or database workloads, effectively every write is a sync write, so the SLOG sees a write volume no single data vdev ever experiences.
Two properties of the ZIL make this worse than it looks. First, ZIL data is transient: entries are freed once their transactions commit during TXG sync, so the SLOG holds only a few seconds of data at any time while absorbing an enormous lifetime write volume. Second, the SLOG is write-only in normal operation. It is only ever read during pool import after an unclean shutdown, to replay acknowledged sync writes. You get no read-side warning signs; the device just keeps absorbing writes.
flowchart LR A[Sync writes: fsync, O_SYNC, NFS] --> B[ZIL] B --> C[SLOG device] D[Async writes] --> E[TXG in RAM] E --> F[Pool data vdevs] C -. read only after crash .-> G[ZIL replay at import]
What happens when the SLOG wears out
Endurance exhaustion on an SSD is not like a failing HDD with months of growing latency and reallocated sectors. The degradation curve is a cliff: sudden failure when endurance is exhausted, with no graceful degradation phase for ZFS to notice in advance.
What a SLOG failure does to the pool:
- SLOG failure during normal operation is not data loss. ZFS falls back to writing the ZIL on the pool’s data vdevs. Data already acknowledged is safe.
- The failure is a performance event, not an availability event. Sync write latency jumps from SLOG-speed to pool-speed, which can be a 10x to 100x regression for NFS and database workloads. The pool state does not change to DEGRADED, because the SLOG is not a data device.
zpool status -xmay still report all pools healthy while applications are timing out. - The one losing combination is an unmirrored SLOG plus a crash or power loss before the next TXG commits. If the SLOG fails and the system goes down in the same window, the ZIL entries for recently acknowledged sync writes are gone. This is why production SLOG devices should be mirrored: a single SLOG failure must never coincide with a sync-write durability gap.
Because a failed SLOG does not degrade pool state, the failure is invisible to the most common health check. You catch it by checking the log vdev explicitly in zpool status, by watching sync write latency, and, long before that, by watching the wear counters.
Why ZFS cannot show you SLOG wear
There is no ZFS-level kstat for SLOG write volume. This trips up experienced operators because the obvious candidate looks right and is wrong: l2_write_bytes in /proc/spl/kstat/zfs/arcstats counts bytes written to the L2ARC, not to the SLOG. If you alert on it as a SLOG proxy, you are monitoring the wrong device.
The ZIL kstats that do exist (/proc/spl/kstat/zfs/zil) track commit activity: zil_commit_count, zil_commit_writer_count, zil_commit_stall_count, zil_commit_error_count. These tell you the ZIL is busy and whether commits are stalling or erroring, but they do not give you bytes written to the log device.
So wear monitoring must come from the device itself, via SMART and NVMe health data:
- NVMe drives report
Percentage_Used, the controller’s estimate of consumed endurance as a percentage of the rated budget. - SATA/SAS SSDs report attributes such as
Media_Wearout_Indicatoror equivalent vendor wear counters, plus total host writes. - Total bytes written against the rated TBW (terabytes written) from the manufacturer’s spec sheet gives you an absolute endurance budget independent of the SMART percentage.
# Check SLOG device wear (NVMe example)
smartctl -a /dev/nvme0 | grep -iE "percentage_used|data_units_written"
# SATA/SAS SSD wear attributes
smartctl -A /dev/sdX | grep -iE "wear|reallocat|pending"
# Confirm which device is the SLOG and its state
zpool status <pool>
The logs section of zpool status shows the SLOG vdev, its state, and its error counters. Any non-ONLINE state or non-zero error counts on the log vdev is a ticket.
Estimating runway and setting a replacement threshold
SMART wear indicators are counters, not alerts. You have to trend them. The useful calculation is:
Days remaining = (Rated endurance - Lifetime writes) / Daily write rate
For Percentage_Used, the equivalent is: sample the value weekly, compute the percent consumed per week, and project the date you cross your replacement threshold. A SLOG on a busy NFS pool can consume several percent per month, which looks harmless until you realize the device will cross 70% inside a year.
Replacement thresholds:
- Replace the SLOG at roughly 70% wear for production workloads. SLOG and L2ARC devices get a more aggressive threshold than data drives (commonly 80%) because their failure is sudden, their workload is concentrated, and the blast radius is every sync-writing application on the pool.
- Trend the rate, not just the level. A device at 40% with a flat rate is fine. A device at 40% that added 15 points last quarter has a date with your maintenance window.
- Mirror the SLOG. With a mirrored log vdev, one device hitting its wear limit is a routine replacement, not a sync-write outage risk. Create the mirror with
zpool add <pool> log mirror <devA> <devB>.
Replacing a worn SLOG
Replacement is orderly when you do it before failure. SLOG removal through ZFS (zpool remove on the log device) is a clean, controlled operation; an endurance-exhaustion failure is not.
# 1. Confirm current log vdev layout
zpool status <pool>
# 2. Replace in place (preferred; keeps redundancy if mirrored)
zpool replace <pool> <old-slog-device> <new-slog-device>
# 3. Or remove the worn device and add the new one
zpool remove <pool> <old-slog-device>
zpool add <pool> log <new-slog-device>
Operational notes:
- Do this during a normal maintenance window. During the swap, sync writes temporarily use the remaining mirror leg or fall back to the pool ZIL, so sync latency may rise briefly.
- After replacement, reset your wear baseline for the new device and remove the old device’s wear data from your trending.
- If wear accumulated faster than expected, reconsider the device class: the SLOG should be chosen for endurance, not just latency. A device that wore out in 18 months under your sync workload will do it again.
To reduce SLOG wear at the source, audit which datasets actually need synchronous semantics. sync=standard (the default) only involves the ZIL when the application requests it; sync=always forces every write through the ZIL and multiplies SLOG write volume. sync=disabled bypasses the ZIL entirely, but it sacrifices crash durability for acknowledged writes and is not appropriate for databases or anything that relies on fsync. Treat it as a workload decision, not a wear workaround.
Signals to watch in production
| Signal | Why it matters | Warning sign |
|---|---|---|
SMART Percentage_Used / wear attribute | Direct measure of consumed endurance; the only real SLOG wear signal | Crossing 70%, or climbing several points per month |
| Total bytes written vs rated TBW | Absolute endurance budget independent of SMART estimation | Trending toward the manufacturer rating |
| Wear rate (percent per week/month) | Drives runway estimation and replacement scheduling | Implies replacement date inside the next maintenance window |
Log vdev state in zpool status | SLOG failure does not degrade pool state; this is the only place it shows | Any non-ONLINE state or non-zero errors on the log vdev |
zil_commit_stall_count / zil_commit_error_count | Commit stalls and errors point at ZIL/SLOG trouble | Incrementing counters |
Sync write latency (zpool iostat -l, syncq_wait) | A worn or failed SLOG shows up as sync latency regression before anything else | Sustained rise against baseline with reads unaffected |
One correlation is worth memorizing: write latency rising while read latency stays normal, with the pool fully ONLINE, is the signature of a ZIL/SLOG problem, not a data disk problem.
How Netdata helps
- Device-level SMART collection tracks
Percentage_Usedand wear attributes for the SLOG device continuously, so the wear trend exists as a time series instead of a quarterly surprise. - ZFS kstat collection covers the ZIL commit counters (
zil_commit_stall_count,zil_commit_error_count) and the arcstats family, so you can watch ZIL health alongside device health. It also makes the L2ARC/SLOG distinction explicit, sincel2_write_byteslives in arcstats and belongs to the cache device. - Pool latency and queue metrics from
zpool iostatlet you correlate a sync-latency regression with log vdev state and confirm the fallback-to-pool-ZIL pattern. - The correlation that shortens diagnosis: sync write latency rising + log vdev errors + SMART wear near threshold means schedule a replacement. Sync latency rising + log vdev healthy + TXG sync times extending points at pool-side write pressure instead. Same symptom, different root cause, and the signal set separates them in minutes.
Related guides
- ZFS ARC hit ratio low: cache misses, cold caches, and working sets that outgrew RAM
- ZFS zfs_arc_max: capping the ARC without starving read performance
- ZFS ARC and the OOM killer: applications killed while the cache will not shrink fast enough
- ZFS ARC shrinking below c_max: reading memory pressure before latency hits
- ZFS ARC using all memory: the Linux default that eats your RAM
- ZFS capacity planning: runway estimation before the pool fills
- ZFS checksum errors (CKSUM): the definitive signal of silent corruption
- ZFS checksum errors on multiple devices: suspect RAM or the controller, not the disks
- ZFS device UNAVAIL or REMOVED: a disk that fell off the bus
- ZFS dirty data throttling: the write delay that masquerades as slow disks
- How ZFS actually works in production: a mental model for operators
- ZFS monitoring checklist: the signals every production pool needs






