Disk IOPS test
Purpose: check that your validator’s disk is fast enough for X1 block production. This test safely benchmarks random read/write performance (IOPS) using the fio tool.
Run the test
Paste this entire block into your terminal:
# === X1 Validator Disk IOPS Quick Test (safe, file-based) ===
# Target: >= 20,000 IOPS for both 4K random reads and writes
set -euo pipefail
export LC_ALL=C
MNT="${MNT:-/var/tmp}"
SIZE_MB="${SIZE_MB:-2048}"
RUNTIME="${RUNTIME:-30}"
BS="${BS:-4k}"
JOBS="${JOBS:-4}"
IODEPTH="${IODEPTH:-32}"
ENGINE_CANDIDATES=("io_uring" "libaio")
PASS_THRESH="${PASS_THRESH:-20000}"
# Install fio automatically if missing
if ! command -v fio >/dev/null 2>&1; then
echo "Installing fio..."
sudo apt-get update -y >/dev/null 2>&1
sudo apt-get install -y fio >/dev/null 2>&1
fi
ENGINE=""
for e in "${ENGINE_CANDIDATES[@]}"; do fio --enghelp 2>/dev/null | grep -q "$e" && ENGINE="$e" && break; done
[ -n "$ENGINE" ] || { echo "ERROR: Neither io_uring nor libaio available in fio."; exit 1; }
[ -d "$MNT" ] || { echo "ERROR: Mountpoint $MNT does not exist."; exit 1; }
[ -w "$MNT" ] || { echo "ERROR: $MNT is not writable."; exit 1; }
TESTDIR="$MNT/x1-fio-test.$$"
mkdir -p "$TESTDIR"
cd "$TESTDIR"
# --- Robust fio IOPS parser (handles commas, k/M suffixes, different formats) ---
run_fio_and_get_iops () {
local NAME="$1" RW="$2"
fio --name="$NAME" \
--rw="$RW" \
--bs="$BS" \
--ioengine="$ENGINE" \
--direct=1 \
--group_reporting=1 \
--time_based=1 \
--runtime="$RUNTIME" \
--numjobs="$JOBS" \
--iodepth="$IODEPTH" \
--size="${SIZE_MB}m" \
--filename="$TESTDIR/fiofile.bin" \
--random_generator=tausworthe64 \
--fsync_on_close=1 \
--output="$TESTDIR/${NAME}.out" >/dev/null
# Try the headline "read/write: IOPS=..." line first, then fallback to the "iops : avg=..." line.
awk '
BEGIN{ OFMT="%.0f"; want=(tolower("'"$RW"'")=="randread" ? "read" : "write"); val=""; }
{
line=tolower($0)
# Primary match: "read: IOPS=128k" or "write: IOPS=128,532"
if (line ~ "^"want": " && line ~ /(iops|IOPS)=/) {
if (match($0, /(IOPS|iops)=([0-9][0-9,\.]*)([kKmM]?)/, m)) {
gsub(/,/, "", m[2]); # remove thousands commas
num=m[2]+0
suf=tolower(m[3])
if (suf=="k") num=num*1000
else if (suf=="m") num=num*1000000
printf("%.0f\n", num); exit
}
}
# Fallback: summary line "iops : avg=115058.64"
if (line ~ /iops[[:space:]]*:[[:space:]]*.*avg=/) {
if (match($0, /avg=([0-9][0-9,\.]*)/, m2)) {
gsub(/,/, "", m2[1])
num=m2[1]+0
printf("%.0f\n", num); exit
}
}
}
END{
if (NR>0) {} # no-op
}
' "$TESTDIR/${NAME}.out"
}
echo "Running 4K random READ test for ${RUNTIME}s..."
READ_IOPS="$(run_fio_and_get_iops "x1-randread" "randread" || true)"
READ_IOPS="${READ_IOPS:-0}"
echo "READ IOPS: $READ_IOPS"
echo "Running 4K random WRITE test for ${RUNTIME}s..."
WRITE_IOPS="$(run_fio_and_get_iops "x1-randwrite" "randwrite" || true)"
WRITE_IOPS="${WRITE_IOPS:-0}"
echo "WRITE IOPS: $WRITE_IOPS"
# Compare safely even if value is empty
passfail () {
local val="${1:-0}" kind="$2"
if [ "${val:-0}" -ge "${PASS_THRESH:-20000}" ]; then
echo "PASS ($kind ≥ ${PASS_THRESH})"
else
echo "FAIL ($kind < ${PASS_THRESH})"
fi
}
READ_VERDICT=$(passfail "$READ_IOPS" "read")
WRITE_VERDICT=$(passfail "$WRITE_IOPS" "write")
echo "==========================================="
echo "X1 Validator Disk IOPS Results (4K random)"
echo " Read IOPS : $READ_IOPS => $READ_VERDICT"
echo " Write IOPS: $WRITE_IOPS => $WRITE_VERDICT"
echo " Threshold : ${PASS_THRESH} IOPS"
echo " Params : jobs=$JOBS iodepth=$IODEPTH bs=$BS engine=$ENGINE size=${SIZE_MB}MB runtime=${RUNTIME}s"
echo "Logs in : $TESTDIR"
echo "==========================================="
echo ""
echo "=== fio raw output summary ==="
grep -i "iops" "$TESTDIR"/x1-randread.out || true
grep -i "iops" "$TESTDIR"/x1-randwrite.out || true
echo "=============================="
echo "Done."How to interpret results
You’ll see something like:
read: IOPS=128k, BW=499MiB/s
write: IOPS=113k, BW=442MiB/sDisk Type
Expected IOPS
Verdict
HDD
200–500
❌ Too slow
SATA SSD
5k–10k
⚠️ Weak
Consumer NVMe
50k–100k
✅ Good
Datacenter NVMe
100k–250k+
💎 Excellent
If both read and write ≥ 20,000 IOPS → ✅ your disk is ready for X1 mainnet validation.
Last updated

