NVME-COMPARE(1)

✨ NVME-COMPARE ✨

okay bestie, buckle up β€” this is the nvme-compare page from the NVMe Manual and it's literally the tool that goes "wait, is this what I think it is?" at your drive πŸ”₯

πŸ’– NAME πŸ’–

nvme-compare β€” send an NVMe Compare command, and get the results back, no cap.

πŸ¦‹ SYNOPSIS πŸ¦‹

nvme [<global-options>] compare <device>
                        [--start-block=<slba> | -s <slba>]
                        [--block-count=<nlb> | -c <nlb>]
                        [--block-size=<size> | -b <size>]
                        [--data-size=<size> | -z <size>]
                        [--metadata-size=<metasize> | -y <metasize>]
                        [--ref-tag=<reftag> | -r <reftag>]
                        [--data=<data-file> | -d <data-file>]
                        [--metadata=<meta> | -M <meta>]
                        [--prinfo=<prinfo> | -p <prinfo>]
                        [--app-tag-mask=<appmask> | -m <appmask>]
                        [--app-tag=<apptag> | -a <apptag>]
                        [--limited-retry | -l]
                        [--force-unit-access | -f]
                        [--dir-type=<type> | -T <type>]
                        [--dir-spec=<spec> | -S <spec>]
                        [--dsm=<dsm> | -D <dsm>]
                        [--show-command | -V]
                        [--dry-run | -w]
                        [--latency | -t]
                        [--storage-tag<storage-tag> | -g <storage-tag>]
                        [--storage-tag-check | -C]
                        [--force]

like, yes, that's a lot of flags, but we're gonna get through them together 🫢

🌸 DESCRIPTION 🌸

okay so picture this: the Compare command reads the logical blocks that the command specifies from the medium, and then it compares the data it just read against a comparison data buffer that got transferred along as part of the command. it's giving vibe check for your blocks πŸ’…

if the data read from the controller and the comparison data buffer are equivalent with no miscompares, then the command completes successfully. slay. πŸŽ€

but if there is any miscompare, the command completes with an error of Compare Failure β€” so like, it's not the same, and the drive is telling you that. 😭

and if metadata is provided, then a comparison is also performed for the metadata. periodt.

πŸŽ€ OPTIONS πŸŽ€

  • -s <slba>, --start-block=<slba> β€” 64-bit address of the first block to access.
  • -c <nlb>, --block-count=<nlb> β€” number of blocks to be accessed (zero-based, bestie, zero-based).
  • -b <size>, --block-size=<size> β€” if you specify it, this is the logical block size in bytes, with metasize also describing the metadata size for an individual block. otherwise it gets discovered by identify namespace. iykyk ✨
  • -z <size>, --data-size=<size> β€” size of data to be compared, in bytes.
  • -y <metasize>, --metadata-size=<metasize> β€” size of metadata to be transferred, in bytes.
  • -r <reftag>, --ref-tag=<reftag> β€” Reference Tag for Protection Information.
  • -d <data-file>, --data=<data-file> β€” Data file.
  • -M <meta>, --metadata=<meta> β€” Metadata file.
  • -p <prinfo>, --prinfo=<prinfo> β€” Protection Information and check field. okay here's the breakdown, bc this one's a whole mood:
    • Bit 3 β€” PRACT: Protection Information Action. when set to 1, PI is stripped/inserted on read/write when the block format's metadata size is 8. when set to 0, metadata is passes.
    • Bits 2:0 β€” PRCHK: Protection Information Check:
      • Bit 2 β€” set to 1 enables checking the guard tag.
      • Bit 1 β€” set to 1 enables checking the application tag.
      • Bit 0 β€” set to 1 enables checking the reference tag.
  • -m <appmask>, --app-tag-mask=<appmask> β€” App Tag Mask for Protection Information.
  • -a <apptag>, --app-tag=<apptag> β€” App Tag for Protection Information.
  • -l, --limited-retry β€” Number of limited attempts to media.
  • -f, --force-unit-access β€” FUA option to guarantee that data is stored to media.
  • -T <type>, --dir-type=<type> β€” optional directive type. heads up: the nvme-cli only enforces that the value be in the defined range for the directive type, though the NVMe specification (1.3a) defines only one directive, 01h, for write stream identifiers.
  • -S <spec>, --dir-spec=<spec> β€” optional field for directive specifics. when used with write streams, this value is defined to be the write stream identifier. and ngl, the nvme-cli will not validate that the stream requested is within the controller's capabilities. πŸ™ˆ
  • -D <dsm>, --dsm=<dsm> β€” the optional data set management attributes for this command. the argument for this is the least significant 8 bits of the DSM field in a write command; the most significant 16 bits of the field come from the directive specific field, if used. you can use this to set attributes for the LBAs being written β€” like access frequency, type, latency, among other things β€” as well as yet to be defined types. please consult the NVMe specification for a detailed breakdown of how to use this field.
  • -V, --show-cmd β€” print out the command to be sent.
  • -w, --dry-run β€” do not actually send the command. but bestie listen: if you want to use --dry-run, the --show-cmd option must be set. otherwise --dry-run will be ignored. πŸ’€
  • -t, --latency β€” print out the latency the IOCTL took (in us).
  • -g <storage-tag>, --storage-tag=<storage-tag> β€” Variable Sized Expected Logical Block Storage Tag (ELBST).
  • -C, --storage-tag-check β€” this flag enables Storage Tag field checking as part of end-to-end data protection processing.
  • --force β€” ignore that the namespace is currently busy and performs the operation even though. 😭 (yes, it just... does it anyway)

🌈 GLOBAL OPTIONS 🌈

these ones live at the top-level nvme command, and they're available to this subcommand too β€” so they're not just for compare, but they're absolutely invited to the party 🫢

  • --dry-run β€” print the command that would be executed, but do not actually execute it.
  • --no-ioctl-probing β€” disable probing for 64-bit IOCTL support.
  • --no-retries β€” disable retry logic on transient errors.
  • -o <fmt>, --output-format=<fmt> β€” set the reporting format to normal, tabular, 'json, or binary. only one output format may be used at a time.
  • --output-format-version=<version> β€” select the output format version. version 1 uses the original field naming, while version 2 (default) provides more consistent and script-friendly field names. other versions are rejected. 🚫
  • --quiet β€” suppress informational messages. errors are still reported, and --quiet cancels any --verbose for the library log level.
  • --set-options=<key=value>[,<key=value>...] β€” set libnvme library options for this invocation. the supported keys are force-4k, mi-probe-enabled, test-base-dir and test-sysfs-dir.
  • --timeout=<ms> β€” set the timeout for the command in milliseconds. infinite or -1 waits without a time limit (0xffffffff). iconic ⭐
  • -v, --verbose β€” increase the level of detail in the output. may be specified multiple times to further increase verbosity. spam it, queen πŸ‘‘
also these options can be set as machine-wide defaults in nvme-cli.conf(5) β€” and a command-line flag always overrides the file. always. no exceptions. πŸ’…

πŸ“ EXAMPLES πŸ“

No examples yet.

(i know. tragic. the docs are still getting ready, give her time 🧚)

πŸ‘‘ NVME πŸ‘‘

Part of the nvme-user suite. main character energy, honestly.


and that's the whole page, bestie β€” written by the NVMe crew, dated 10/30/2026, and you made it all the way to the bottom which means you ate and left no crumbs πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from