NVMe wear-out is one of the few storage failures that usually announces itself months in advance. The announcement is quiet: a monotonically rising percentage_used, a slow drift in available_spare, maybe the first few media_errors. If you only look at current values, you find out when the drive crosses a threshold. If you trend the rates, you can procure before the drive becomes an incident.

This guide is a planning procedure for local PCIe-attached NVMe devices. It turns three wear signals into a replacement date, then cross-checks that date against spare-block consumption and early media failure. It does not apply to NVMe-oF, ZNS, SPDK, or virtualized cloud “NVMe” devices where SMART data is absent, synthetic, or owned by the provider.

The core rule: treat percentage_used as the procurement clock, available_spare as the physical runway, and media_errors as the signal that can invalidate both.

What this projection gives you

A useful endurance runway answers four operational questions:

  • When to buy. Start procurement when percentage_used crosses 80%, or when the projected date to 80% is inside your procurement lead time.
  • When to schedule. Schedule replacement when percentage_used crosses 90%, when available_spare approaches its vendor threshold, or when spare consumption accelerates.
  • When to stop trusting the estimate. New media_errors, critical warning bit 2, or a falling available_spare out of proportion to percentage_used means the smooth wear model is no longer the main risk.
  • When the drive class is wrong. A sudden increase in wear rate usually means the workload changed, the drive is too full, write amplification increased, or a consumer-class drive is doing an enterprise-class job.

Do not page on percentage_used alone. High endurance consumed is a planning signal, not an emergency. The emergency signals are read-only mode, reliability degraded with rising media errors, controller resets, and device disappearance.

Prerequisites

  • Device access. You need read access to the NVMe character device, for example /dev/nvme0. Namespace devices such as /dev/nvme0n1 report block I/O, but SMART wear data is controller-level.
  • A time window. SMART wear counters are coarse and polled. Use at least 14 days for a first trend and 30 days for procurement decisions. Hourly deltas are noise.
  • Drive identity. Record model, firmware, capacity, rated TBW or DWPD, and whether the drive is consumer QLC, consumer TLC, or enterprise TLC. The endurance scale varies enormously: consumer QLC is often in the 100-300 TBW range, while enterprise TLC is commonly specified around 1-10 DWPD.
  • Fill level context. A nearly full drive has higher garbage collection pressure and can wear faster than the same workload on a mostly empty drive. Keep capacity utilization in the same trend view.

Signals to use

SignalSource fieldWhat it contributesMain trap
Endurance consumedpercentage_usedVendor estimate of rated life consumed; monotonic fuseVendor-specific estimate; can exceed 100 and still run
Spare blocksavailable_spare, available_spare_thresholdPhysical margin for bad-block replacement; bit 0 trips at thresholdLast portion depletes non-linearly; threshold varies by vendor
Media failuremedia_errorsEarly proof that ECC and retries are no longer enoughLifetime counter; only rate of increase matters
Host write volumedata_units_written, power_on_hoursCross-check against TBW or DWPD ratingHost-visible writes only; not NAND writes
Reliability assessmentcritical_warning bits 0, 2, 3Drive’s own urgent state: spare low, reliability degraded, read-onlyA single bitmask hides different severities

Collect the raw values with read-only commands:

# Read SMART wear and health fields for one controller
nvme smart-log /dev/nvme0

# Machine-readable form for trending
nvme smart-log /dev/nvme0 -o json | jq '{percent_used, avail_spare, spare_thresh, media_errors, data_units_written, power_on_hours, critical_warning}'

Do not average these values across unlike drive models; trend per model and per workload.

Procedure

  1. Baseline the drive class. Record model, firmware, capacity, rated TBW or DWPD, and current fill level. A projection without the drive class is not actionable, because 5% per month means very different things on a 100 TBW QLC part and a 3 DWPD enterprise part.

  2. Compute the daily endurance rate. Use at least a 14-day window, preferably 30 days:

    daily_pct = (percentage_used_now - percentage_used_then) / days_between_samples
    

    If daily_pct <= 0, discard the window. The counter should not go down; a flat or negative delta means bad samples, stale SMART data, a replaced drive, or a vendor reporting quirk.

  3. Project days to rated end of life:

    days_to_100 = (100 - percentage_used_now) / daily_pct
    

    Also project days to the action thresholds:

    days_to_80 = max(0, (80 - percentage_used_now) / daily_pct)
    days_to_90 = max(0, (90 - percentage_used_now) / daily_pct)
    
  4. Apply the final-10% safety factor. Spare depletion accelerates near end of life, so the last 10% is not linear. Once percentage_used_now >= 90, or once any projection enters the 90-100 band, halve the remaining runway:

    effective_days = days_to_100 / 2
    

    This is deliberately conservative. The goal is to replace before spare exhaustion and read-only mode, not to prove the datasheet exact.

  5. Compute the spare-block runway. Convert available_spare decline into a daily drop over the same window:

    spare_daily_drop = (available_spare_then - available_spare_now) / days_between_samples
    spare_days = (available_spare_now - available_spare_threshold) / spare_daily_drop
    

    Treat spare_days as invalid if spare_daily_drop <= 0. A long flat period followed by a step down is common on some controllers; use a longer window before trusting it.

  6. Take the minimum credible runway. Use the smaller of the endurance runway and spare runway, then downgrade confidence if media_errors is increasing. A smooth percentage_used projection does not protect you from a NAND batch problem that shows up first as media errors.

  7. Cross-check with host write volume. Convert data_units_written to bytes using 512,000 bytes per unit (thousands of 512-byte units):

    tb_written = data_units_written * 512000 / 1e12
    

    Compare lifetime TB written with rated TBW where the vendor publishes one. For DWPD-rated drives, estimate recent DWPD from the delta in data_units_written, drive capacity, and elapsed days. This is host-visible write volume: the FTL can write more to NAND than the host wrote, so standard SMART cannot give you true write amplification.

  8. Classify the action.

    StateTriggerAction
    Normalpercentage_used < 80, spare above 2x threshold, no new media errorsKeep trending monthly
    Procurepercentage_used >= 80, or projected 80% date inside lead timeBuy replacement, validate spares, check fleet siblings
    Schedulepercentage_used >= 90, spare near 2x threshold, or spare runway shorter than endurance runwayPlan migration before failure signals appear
    Replace nowspare at or below threshold, critical warning bit 0, bit 3 read-only, or bit 2 with rising media errorsProtect data first, then replace
    Wrong classwear rate spikes after workload change, or rate exceeds class expectationFix workload or move to higher-endurance drive
flowchart TD
  A[Collect SMART wear fields] --> B[Trend percentage_used and available_spare]
  B --> C[Project endurance and spare runway]
  C --> D{Media errors rising or critical_warning set?}
  D -- yes --> E[Protect data and replace]
  D -- no --> F{Runway inside lead time?}
  F -- no --> G[Keep monthly trend]
  F -- yes --> H[Procure at 80 and schedule by 90]

Reading the result

A worked example with synthetic numbers: a drive goes from 61% to 64% percentage_used in 30 days. daily_pct = 3 / 30 = 0.1. At 64%, days_to_100 = 36 / 0.1 = 360 days, days_to_80 = 160 days, and days_to_90 = 260 days. If procurement takes 90 days, procurement starts when projected days-to-80 falls below 90, not when the drive is already at 80.

Now change one input: available_spare falls from 41 to 38 over the same 30 days with a threshold of 10. spare_daily_drop = 3 / 30 = 0.1, so spare_days = 28 / 0.1 = 280. The spare runway is shorter than the endurance runway to 100 and close to the 90% schedule window. This drive should be scheduled earlier than the percentage_used-only estimate suggests.

If media_errors increases during the window, stop presenting the result as a date. Present it as a risk state: verify redundancy, rewrite or back up cold data if your architecture requires it, and replace during the next maintenance window. If critical warning bit 2 is also set, treat it as active degradation rather than planning.

Common pitfalls

  • Using one sample. A single SMART read tells you state, not runway. Without rate of change, 30% used can be safe for years or five months from replacement.
  • Trusting 100% as a cliff. The NVMe model allows percentage_used above 100, and many drives keep running past it. Operational risk rises, but the exact failure point is vendor- and workload-dependent.
  • Ignoring the spare curve. available_spare can remain high for a long time and then fall faster near the end. The final 10% needs a safety factor, not a straight line.
  • Confusing host writes with NAND writes. data_units_written excludes FTL write amplification. It is useful for workload cross-checks, not for proving exact cell wear.
  • Averaging unlike drives. Consumer QLC, consumer TLC, and enterprise TLC have different ratings, reporting behavior, over-provisioning, and failure tolerance.
  • Alerting on the raw bitmask. Critical warning bit 0 is a replacement signal, bit 2 plus rising media errors is active degradation, and bit 3 is write refusal. One alert for critical_warning != 0 hides the response.
  • Forgetting fill level. Drives under heavy garbage collection pressure can wear faster than the same host write rate on a drive with more free space. Keep logical free space in the same review.

Signals to monitor

SignalWhy it mattersWarning sign
percentage_used rateMain procurement clockSustained increase above baseline, or roughly >1% per week without a planned workload change
available_spare vs thresholdPhysical bad-block marginAt or below 2x threshold, accelerating downward trend, or at/below threshold
media_errors rateEarliest media failure signalAny sustained increase; page-level concern when paired with critical warning bit 2
data_units_written deltaWorkload cross-check against TBW or DWPDWrite rate no longer matches drive class or approved workload
critical_warning bitsDrive’s own urgent assessmentbit 0 spare low, bit 2 reliability degraded, bit 3 read-only
Drive fill levelGC pressure and wear amplification contextSustained operation with little logical free space

How Netdata helps

  • Track nvme.device_estimated_endurance_perc as a trend, not a one-off gauge, so percentage_used rate of change is visible before the 80% and 90% thresholds.
  • Compare nvme.device_available_spare_perc against the vendor spare threshold and watch for acceleration, not only the crossing.
  • Alert on nvme.device_media_errors_rate as a rate, because the lifetime counter never decreases and isolated old errors can be benign.
  • Use nvme.device_io_transferred_count to cross-check host write volume against the endurance trend and expose workload changes that invalidate the projection.
  • Correlate endurance, spare, media errors, temperature, and per-device I/O on one timeline so a wear-rate spike can be tied to a workload, fill-level, or thermal change instead of being treated as a mysterious SMART jump.