Skip to content

How to check NVMe Drives TBW in ESXi with PowerCLI

When working with SSDs, you have to keep an eye on its TBW ("Total Bytes Written" or "Terabytes Written"). A maximum TBW guarantee is typically provided by the vendor in their specifications. This value describes how data can be written to the entire device until the warranty expires. The current value can be checked with S.M.A.R.T.

This article explains how to check the TBW value on NVMe based drives running in an ESXi host with PowerShell or from the command line. If you have a SATA based SSD drive, check this article.

In this example, I'm using the Samsung 950 PRO NVMe based flash drive. The endurance for this device is rated at 400 TBW. Just mentioning that this still is a consumer-grade SSD. The lowest endurance Class for Virtual SAN, for example, starts at 365TBW.

  1. Connect to the ESXi Host with SSH
  2. Identify NVMe drives
    # esxcli nvme device list
    HBA Name  Status  Signature
    --------  ------  ---------------------
    vmhba0    Online  nvmeMgmt-nvme00610000
  3. Get the "Data Units Written" counter. Replace vmhbaX id with the adapter identifies in step 2.
    # esxcli nvme device log smart get -A vmhba0 |grep Written
       Data Units Written: 0xe1c78d
  4. The counter is hexadecimal. Convert it to decimal. This can be done also from the command line, or the Windows Calculator in Programmer mode.
    # printf "%d\n" 0xe1c78d
    14796685
  5. The counter is a little bit unusual as it refers to 1000 of 512-byte units. Multiply the result with 512000 and divide it by 1TB (1.099.511.627.776) for TBW or 1GB (1.073.741.824) for GBW.14796685 * 512000 / 1099511627776 = 6,9 TBW
    14796685 * 512000 / 1073741824 = 7055 GBW

You can also use this one-liner to do the calculation for GBW:

# i=$(esxcli nvme device log smart get -A vmhba0 |grep Written | cut -d ":" -f 2); echo $(($(printf "%d\n"
$i)*512000/1073741824)) GBW
7055 GBW

or TBW:

# i=$(esxcli nvme device log smart get -A vmhba0 |grep Written | cut -d ":" -f 2); echo $(($(printf "%d\n"
$i)*512000/1099511627776)) TBW
6 TBW

PowerShell / PowerCLI Script

The following PowerShell script displays a report about all NVMe devices in a vCenter Server instance.

$AllInfo = @()
Foreach ($vmhost in Get-VMHost |Where-object {$_.powerstate -eq "PoweredOn"}) {
    $esxcli = get-esxcli -V2 -vmhost $vmhost
    $devices = $esxcli.nvme.device.list.Invoke()
    Foreach ($device in $devices) {
        $nvme = $esxcli.nvme.device.get.CreateArgs()
        $nvme.adapter = $device.HBAName
        $Info = "" | Select VMHost, HBA, Model, DataUnitsWritten, GBW, TBW
        $Info.VMHost = $vmhost.Name
        $Info.HBA = $device.HBAName
        $Info.Model = ($esxcli.nvme.device.get.invoke($nvme) | Select-Object ModelNumber).ModelNumber
        $Info.DataUnitsWritten = [int]($esxcli.nvme.device.log.smart.get.Invoke($nvme) |Select-Object DataUnitsWritten).DataUnitsWritten
        $Info.GBW = [math]::round($Info.DataUnitsWritten*512000/1Gb)
        $Info.TBW = [math]::round($Info.DataUnitsWritten*512000/1Tb, 1)
        $AllInfo += $Info
    }
}

$AllInfo

Output:

VMHost           : esx4.virten.lab
HBA              : vmhba0
Model            : Samsung SSD 950 PRO 256GB
DataUnitsWritten : 14797188
GBW              : 7056
TBW              : 6,9

512 Bytes vs. 4k Blocksize

According to the counter description, it does not matter whether the physical block size is 512 bytes or larger. The value is always calculated to 512 Bytes:

Data Units Written: Contains the number of 512 byte data units the host has written to the controller;
this value does not include metadata. This value is reported in thousands (i.e., a value of 1 corresponds to 1000 units of 512 bytes written) and is rounded up. When the LBA size is a value other than 512 bytes, the controller shall convert the amount of data written to 512 byte units.
For the NVM command set, logical blocks written as part of Write operations shall be included in this
value. Write Uncorrectable commands shall not impact this value.

2 thoughts on “How to check NVMe Drives TBW in ESXi with PowerCLI”

  1. It's incorrect. At least for Kingston SA2000.

    I did very simple test. I have uploaded 80MB file and 5.59GB file.
    For the first file i got
    0x627004 before or 6451204 data units
    and
    0x627158 after or 6451544 data units
    File size is 85813937 bytes
    So 85813937 / (6451544 - 6451204) ~=2523934. Like /2 from what is in this article.

    For the second file i got
    0x627a13 before or 6453779 data units
    and
    0x62d6cb after or 6477515 data units
    File size is 6006587392bytes
    So 6006587392 / (6477515 - 6453779) ~=253058. Like /2 from what is in this article.

    So the correct number is 256000, not 512000

Leave a Reply

Your email address will not be published. Required fields are marked *