N5 MAX: the final verdict
Five NVMe slots (four at PCIe Gen4 x1, one at Gen4 x4), a Ryzen AI Max+ 395 with 128 GB unified memory, and a seven-stage sealed campaign across ZFS, btrfs and mdadm, local LLM inference, a one-hour soak, USB ingest and drive-failure rebuilds. All figures come from sealed result.json files or the lab’s own report tooling, as of 2026-10-08.
1 · Executive summary
Each headline finding below carries its evidence: stage, layout, test id and the run timestamp of the sealed case.
Recommended default stays RAIDZ1 5-wide, and stage 7 now backs it.
Degraded with one member out, RAIDZ1 still read 93.51 % of healthy sequential throughput and resilvered in 1,740 s at 1.1656 GB/s. btrfs raid5 fell to 5.87 % and took 3,720 s at 0.5498 GB/s.
S7 · zfs-raidz1 / btrfs-raid5 · STO-09 STO-01_seq_read_1M_j4 · runs 2026-09-24-19.58 / 2026-09-24-05.07Fastest measured is now a tie: btrfs raid5 and mdadm raid5 (cold seq read).
btrfs raid5 9.034 GB/s at 14.43 TiB, mdadm+ext4 raid5 9.035 GB/s at 14.41 TiB. Both are on the capacity × cold-read Pareto frontier from the lab’s Pareto tool. RAIDZ1 5-wide reads 7.83 GB/s (1.154× behind btrfs raid5).
S5 · btrfs-raid5 / mdadm-ext4-raid5 · STO-01_seq_read_1M_j4 · runs 2026-09-14-13.57 / 2026-09-25-18.53The “mdadm is 8× slower” anomaly is resolved: it was a link fault, not mdadm.
SN1 had trained at Gen1 2.5 GT/s x1 in every original mdadm cell (#72), which pinned seq read at 1.14 GB/s. The reruns at Gen4 read 9.035 GB/s.
S5 · mdadm-ext4-raid5 · STO-01_seq_read_1M_j4 · run 2026-09-25-18.53 (superseded 2026-09-15-00.41)mdadm parity writes fast in sequence but collapses on 16K random writes.
mdadm raid5 has the highest cold sequential write (5.04 GB/s vs btrfs raid5 4.066), but only 2,489 IOPS on 16K random writes vs btrfs raid5 22,981. That is partial-stripe read-modify-write. mdadm raid6 is the same: 2,313 IOPS.
S5 · mdadm-ext4-raid5 · STO-01_seq_write_1M_j4, STO-02_rand_write_16k_j4 · run 2026-09-25-18.53The ZFS-vs-btrfs write gap in the FS controls is a drive-state effect, not a filesystem verdict.
The ZFS stage-1 cells fully preconditioned their members before measuring, and the btrfs fs-control cells did not (per the lab’s backend notes). There btrfs raid5 wrote 4.066 GB/s vs RAIDZ1 0.718. Under STO-09 S1 (same protocol, file-on-FS, both after the same 50 % incompressible fill) RAIDZ1 wrote 4.499 GB/s and btrfs raid5 2.78 GB/s.
S7 S1 · zfs-raidz1 / btrfs-raid5 · STO-01_seq_write_1M_j4 · runs 2026-09-24-19.58 / 2026-09-24-05.07The four x1 slots tax sequential work about 3×, but barely touch random and sync work.
One NM790 at x4 vs x1: seq read 5.888 vs 1.8 GB/s (3.27×), 4K random read 41,318 vs 35,116 IOPS (1.18×), sync 16K 1,398 vs 1,283 (1.09×). One x1 drive reaches 91 % of the 1.969 GB/s lane.
S1 · single-x1 / single-x4 · STO-01, STO-02, STO-04 · runs 2026-09-13-13.00 / 2026-09-12-19.42ZFS RAID10 is the sync-write layout; RAIDZ1 pays for parity on sync.
Cold sync 16K: RAID10 1,675 IOPS vs RAIDZ1 415. primarycache=metadata does not help sync (RAIDZ1 256), but it lifts 4K random reads by 50.2 % on RAIDZ1 and 58.7 % on RAID10.
S1/S2 · raid10 / raidz1 · STO-04_sync_write_16k_j4, STO-02_rand_read_4k_j4 · runs 2026-09-13-15.49 / 2026-09-13-17.14Once a model is resident, the pool does not matter for inference.
Gemma 4 26B tg128 is 50.15 tok/s on btrfs and 50.08 on ZFS. Qwen3.8-27B (gufo-model-bench) decodes 12.44 tok/s from btrfs cold and 12.34 from ext4 warm. Pools differ only in cold load (5.035 s vs 6.758 s for Gemma).
S3 · btrfs raid5 / ZFS RAIDZ1 · AI-01 card + load rail · runs 2026-09-22-06.02 / 2026-09-23-04.57We sit below the Minisforum vendor floor on all 16 comparisons.
Ours ÷ floor ranges from 0.7128 to 0.9715. gpt-oss-120b HIP is 0.8562 (pp512) and 0.8976 (tg128). Decode on Gemma 4 and Qwen3.5-122B is the furthest behind (0.7128, 0.7252 HIP). The vendor states no conditions beyond ngl 99 and FA on.
S3 · btrfs raid5 · AI-01 vendor group · run 2026-09-23-15.03Vulkan decodes faster, HIP prefills faster, and Vulkan loads much slower.
Across the four floor models, Vulkan tg128 is 1.062–1.107× HIP and HIP pp512 is 1.038–1.082× Vulkan. Vulkan cold load takes 1.34–5.22× as long (gpt-oss-120b 49.375 s vs 11.256 s).
S3 · btrfs raid5 · AI-01 vendor group + load rail · HIP/Vulkan cellsStreaming models larger than memory is a load-time story, and ZFS loses it.
Kimi K2 (streamed) cold load took 38.334 s on btrfs vs 181.147 s on ZFS (primarycache=all). Decode is unusable either way: 1.09 / 1.55 tok/s.
S3 · btrfs raid5 / ZFS RAIDZ1 · AI-01 kimi-k2 streamed · runs 2026-09-29-03.21 / 2026-09-29-13.35Thermals are a non-issue for an hour of sustained work.
In the 1-hour RAIDZ1 soak, mixed 70/30 held 0.886 GB/s and was steady, with drives peaking at 59.85 °C and the SoC at 52.0 °C. The sequential-write soak (1.178 GB/s) was not steady.
S4 · raidz1 · SOAK-02_mixed_70r30w_16k_j4 · run 2026-09-12-14.31
2 · Setup & method
Platform
Minisforum N5 MAX (Ryzen AI Max+ 395, Radeon 8060S iGPU, 128 GB LPDDR5X unified memory). Five 4 TB Lexar NM790 NVMe drives, labelled SN1–SN5. SN1–SN4 sit on Gen4 x1 links (1.969 GB/s each) and SN5 on Gen4 x4 (7.88 GB/s). The NM790 is DRAM-less (HMB) and has no power-loss protection. Five 3.5″ SATA bays hang off a JMB58x bridge on a shared Gen3 x2 uplink; they were not benchmarked. The box has 2×10GbE.
Campaign
Stage 1/2: ZFS layouts in cold (primarycache=none) and metadata regimes. Stage 3: 21 AI cells. Stage 4: one-hour soaks. Stage 5: btrfs and mdadm+ext4 controls, cold and warm. Stage 6: USB. Stage 7: drive failure and rebuild (STO-09). Stage 8: write-hole, deferred.
Rules applied in this report
Storage claims use Protocol B cases (derived durations; params.protocol starting with B-) and the lab selector’s published case per subject (the lab’s publish selector). Non-steady cases (rails.steadiness.steady == false) are drawn hatched or flagged red. PROVISIONAL (≥2× spread against the subject’s own history) and RUN SUPERSEDED figures are marked and never carried into a conclusion. deprecated-fixed60, preliminary-omega, calibrate-mode cells and link-downtrained runs are excluded.
Regimes. Cold (ZFS primarycache=none, or dropped caches) is the layout story. Metadata and warm are separate regimes. Warm sequential reads converge on the DRAM ceiling (35.685–36.74 GB/s whatever the layout), so they are not layout evidence.
Access method. ZFS stage 1/2 random, mixed and sync tests ran on zvols; btrfs and mdadm ran on files. Random IO is compared within a stack only. Sequential STO-01 is file-on-FS everywhere.
Selector accounting at build time: 252 run directories, 964 published subjects. Case verdicts: VOID 250, PASS 1428, FAIL 127, UNMEASURED 37. Coverage of the campaign matrix:
| stage | sealed | no result.json | lost | matrix status |
|---|---|---|---|---|
| Stage 1 | 13 | 0 | 0 | passed 13 |
| Stage 2 | 10 | 0 | 0 | passed 10 |
| Stage 3 | 21 | 0 | 0 | passed 21 |
| Stage 4 | 2 | 0 | 0 | passed 2 |
| Stage 5 | 12 | 0 | 0 | passed 12 |
| Stage 6 | 0 | 0 | 1 | passed 1 |
| Stage 7 | 10 | 0 | 0 | passed 3, failed 7 |
| Stage 8 | 0 | 0 | 0 | deferred (write-hole, #59) |
3 · Storage findings
3.1 Layouts: the tradeoff compass
Plotting capacity against cold sequential read shows the whole decision on one chart. The parity layouts on all five drives cluster at the top. With SN5 at x4 they read 9.0 GB/s (btrfs raid5/6, mdadm raid5/6) and 8.911 GB/s (RAIDZ2). RAIDZ1 sits a step lower at 7.83 GB/s with the second-highest usable capacity of any candidate (14.11 TiB, against 14.43 TiB for btrfs raid5). The mirrors pay half the raw capacity: ZFS RAID10 holds 6.71 TiB at 7.024 GB/s.
3.2 Every layout, six workloads
Three patterns hold up. (1) Every parity layout reaches 9.0 GB/s sequential reads once SN5’s x4 lane is a member. The x1 members are the limit, not the filesystem. (2) Sync writes favour mirrors on ZFS (RAID10 1,675 vs RAIDZ1 415 IOPS). On files they favour btrfs over mdadm raid10 (2,153 vs 323). (3) mdadm parity is a sequential-write specialist: highest seq write (5.04 GB/s), worst 16K random write (2,489 IOPS).
RAIDZ1 cold mixed 70/30 (757 IOPS) is PROVISIONAL: its own prior good value was 14,582 IOPS, a 19× spread (lab storage report). Do not quote it.
3.3 Cold vs metadata
primarycache=metadata keeps the indirect blocks in ARC, so random reads stop paying for metadata fetches. 4K random read rises 50.2 % on RAIDZ1 and 58.7 % on RAID10. Sync writes do not improve, and on RAIDZ1 they fall (415 → 256 IOPS). Sequential reads barely move. Production pools would normally run primarycache=all, which is warmer still, so the cold numbers here are a floor.
3.4 The x1 lane tax
One x1 drive reads 1.8 GB/s, 91 % of its 1.969 GB/s lane, and ZFS RAID10 over four x1 drives reads 3.90× that. So the striping works, and the lanes are the ceiling. Small-block random and sync IO are bound by the drive’s controller and flash, not the link. The four x1 slots are therefore a sequential-bandwidth tax, not a responsiveness tax.
3.5 ZFS vs btrfs vs mdadm
Healthy sequential. On the fs-control battery, btrfs raid5 out-reads RAIDZ1 (9.034 vs 7.83 GB/s at j4; 9.033 vs 6.748 at j1) and out-writes it by 5.66× (4.066 vs 0.718). That write gap does not survive a like-for-like test. STO-09 S1 runs the same file-on-FS protocol on both after the same 50 % incompressible fill. There RAIDZ1 wrote 4.499 GB/s and btrfs raid5 2.78. Reads kept their order: RAIDZ1 7.434 vs btrfs 9.045 GB/s.
The likeliest explanation is NM790 write state. The ZFS stage-1 cells fully wrote their zvols and benchmark file before measuring. The btrfs fs-control cells got no equivalent preconditioning (mkfs.btrfs takes seconds), as the lab notes in its backend code. The soak and stage-7 control show this drive slows sharply once its SLC cache is spent (§3.7, §6). The fs-control seq-write gap therefore compares different drive states, not filesystems.
Random IO cannot be ranked across stacks from this campaign: ZFS used zvols (volblocksize-bound), btrfs and mdadm used files. In STO-09 S1, ZFS 4K random reads on a recordsize=1M dataset ran at 0.033 GB/s against btrfs 2.226 GB/s. That is mostly whole-record read amplification of 1M records. It is a tuning artefact, and the reason a VM or database dataset needs a small recordsize or a zvol.
3.6 Write amplification
Every layout amplifies writes by what its geometry predicts: mirrors 2.006× (ZFS), 2.002× (btrfs), 1.999× (mdadm); 5-wide single parity 1.245× / 1.255× / 1.25×. Double parity sits slightly above the 5/3 expectation on btrfs (1.764×) and mdadm (1.716×), and close to it on RAIDZ2 (1.679×). For endurance on a no-PLP, DRAM-less drive, RAIDZ1 writes 38 % fewer flash bytes per logical byte than a ZFS mirror.
3.7 Degraded, rebuild and the write return (stage 7)
Reads with a drive out. ZFS reconstructs from parity at nearly full speed: RAIDZ1 93.51 %, loaded 97.11 %, RAIDZ2 59.55 %. btrfs raid5 and raid6 collapse to about 0.53 GB/s (5.87 % / 5.86 %), whichever member failed, including the x4 SN5 (5.86 %). btrfs raid10 keeps 71.19 %.
Rebuild. ZFS resilvers only allocated blocks, at 1.1656–1.3828 GB/s (29–28 min at 50 % fill). btrfs replace ran 0.5498 GB/s on raid5 (62 min) and 0.3207 GB/s on raid6 (106 min). The replacement received its allocated-only share as predicted (observed/predicted 1.002 on zfs-raidz1, lab storage report).
The write return. All arms got their reads back (S4 93.17–112.7 % of S1). Every ZFS arm and btrfs raid6 failed the harness’s S4 write test (more than 10 % below S1): RAIDZ1 39.32 %, RAIDZ2 46.95 %, btrfs raid6 32.67 %.
The preregistered no-failure control ran the same sequence with no failure and no rebuild. It returned 66.58 % and 67.71 % of S1, with S4/S2 = 0.9986 / 1.0167. So roughly two-thirds of the S4 level is what these drives deliver after the write volume of S1–S2 alone. The extra loss in the failure arms (RAIDZ1 down to 39.32 %) is failure- or rebuild-specific by the preregistered rule.
The lab report places the knee at about 2.3–2.4 TB written per survivor. Idle and TRIM recovery rungs did not restore the rate. This is a drive write-state and endurance characteristic; it says nothing about data integrity either way.
-m raid1c3 protects metadata only. The lab’s write-hole harness (#59) was built but never run (stage 8 deferred; a sysrq blocker), so this campaign adds no data either way. Combined with the 5.87 % degraded read, btrfs raid5/6 is not recommended for data you cannot re-download.3.8 Soak and thermals (stage 4)
One-hour soaks on RAIDZ1 and RAID0, metadata regime. RAIDZ1 mixed 70/30 held 0.886 GB/s (54,107 IOPS, steady). Drives peaked at 59.85 °C and the SoC at 52.0 °C. RAID0 mixed held 1.616 GB/s (steady, drives 60.85 °C). The sequential-write soaks were not steady: RAIDZ1 1.178 GB/s, RAID0 1.473 GB/s. That is the same post-cache write sag as in stage 7, not thermal throttling: drive temperatures stayed under 60 °C.
3.9 USB ingest (stage 6)
The campaign’s stage-6 STO-13 cell passed, but its result was lost: it was written to a tmpfs scratchpad that a host reboot wiped. The post-campaign variant STO-13b (a USB-attached NVMe ↔ RAIDZ1 5-wide, 200.74 GiB corpus, different OS image) recorded 905.6 MB/s reading from USB into the pool and 376.2 MB/s writing out (rsync including the sync drain). The pool was not the limit in either direction. The enclosure fell back from UAS to usb-storage, so treat these as a floor for this enclosure, not for the port. Integrity: 0 failures.
4 · AI findings
Stage 3 ran llama.cpp (HIP/ROCm and Vulkan/RADV) on 11 models, from a 0.6B smoke model to Kimi K2 streamed from disk. Most cells load from cold btrfs raid5; paired cells load from ZFS RAIDZ1 (primarycache=all, ARC cold at start). All 21 cells passed. The lab’s status table still lists 21 per-test rows as UNMEASURED (#67/#68). Full table in the appendix.
4.1 Throughput per model
Resident models (HIP, pp512 / tg128 tok/s): gpt-oss-20b 1,488.02 / 75.49; Gemma 4 26B-A4B 1,130.87 / 50.15; gpt-oss-120b 564.01 / 53.12; Qwen3.5-122B-A10B 308.21 / 22.97; dense Qwen3.8-27B Q4 332.94 / 12.59; DeepSeek V4 Flash IQ2_XXS 27.35 / 15.26. Streamed models are not interactive: DeepSeek V3.1 Q2 1.78 and Kimi K2 1.09 tok/s decode.
4.2 Cold load, resident, streamed
Resident. Layout is irrelevant to pp and tg. Gemma 4 on btrfs vs ZFS: 1,130.87 vs 1,136.82 pp512, 50.15 vs 50.08 tg128. Qwen3.8-27B decodes 12.44 tok/s off cold btrfs and 12.34 off a warm ext4 USB boot. Cold load is where pools differ, and only modestly for resident models: 5.035 s btrfs vs 6.758 s ZFS for Gemma. Backend matters more than layout: Vulkan cold loads take 1.34–5.22× as long as HIP on the same pool. Streamed models (larger than practical GPU memory, read via mmap with ~21× read amplification) load 4.73× slower from ZFS (Kimi K2), although decode stays at 1–2 tok/s either way.
The DeepSeek V3.1 streamed cell’s load-rate field (49.927 GB/s) is mmap-deferred bytes over wall time, not a pool rate. Its pool rail read 3.761 GB/s.
4.3 Prefill and decode with context
Prefill holds within a few percent to 8k for the MoE models and drops to 457.82 tok/s at 32k for gpt-oss-120b (81 % of pp512). The dense Llama-2-7B falls hardest (432.08 tok/s at 32k, 33 %).
Decode at 55k keeps 86.8 % on Qwen3.5-122B but only 59.0 % on gpt-oss-120b (31.24 tok/s). The fastest decoders lose the largest share, because the per-token KV read is a bigger fraction of a fast token.
Stage-3 curves stop at 32k (prefill) and 55k (decode). The gufo-model-bench rows carry Qwen3.8-27B to 131,072 tokens: pp2048 329.8 → 130.25 tok/s.
KV-cache quantisation was not run. Every cell used f16 KV. There are no q8_0 rows (#61).
Speculative decoding (USB live boot, ext4, post-campaign, gufo DFlash2): Qwen3.8-27B tg128 rises from 12.34 to 22.68 tok/s on prose (1.84×). That is the largest single decode lever measured on this box for a dense model.
4.4 Which layout helps AI
For resident models, none: put models wherever capacity is convenient. Cold load favours btrfs slightly for resident models (5.035 vs 6.758 s) and strongly for streamed ones. If you plan to stream models larger than memory, keep them on a non-ARC filesystem or a dataset with primarycache=metadata. The second option is a recommendation from mechanism; it was not tested here. For a RAG box the deciding properties are the storage ones: degraded reads, rebuild time, and capacity for embeddings and documents. All three point to RAIDZ1.
5 · Competitive analysis
External figures are quoted as “X reports Y”, with condition differences noted. None of them is our result.
| Source | Model / test | They report | Ours (sealed) | Conditions differ |
|---|---|---|---|---|
| Minisforum (vendor floor) | gpt-oss-120b pp512/tg128 | 668.79 / 59.3 | 572.64 / 53.23 | llama-bench ngl 99 FA on; nothing else stated. We add -lm dio. |
| Minisforum (vendor floor) | Qwen3.5-122B / gpt-oss-20b / Gemma 4 26B tg128 | 31.76 / 83.09 / 70.33 | 23.03 / 75.31 / 50.13 (HIP) | as above. Decode is our largest shortfall. |
| ITPro | gpt-oss-20b decode, Vulkan | 72.9 tok/s (ROCm “40+”) | 80.70 VK / 75.49 HIP | Ollama-style chat prompt vs llama-bench tg128; their ROCm stack evidently older. |
| ITPro | Gemma 4 26B decode | 44 tok/s | 50.15 HIP / 55.40 VK | Ollama, default ~30 GB GPU memory ceiling. |
| ServeTheHome | Beelink GTR9 Pro (same silicon) gpt-oss-120b | 31.41 tok/s | 53.12 | LM Studio, out-of-box 96 GB allocation, different chassis. |
| ServeTheHome | N5 Max, Qwen3.6 27B dense | ~9 tok/s | 12.59 (Qwen3.8-27B Q4) | Different model generation and FP8 vs Q4 weights: shape only. |
| MLPerf v6.1 edge (Atlas) | Qwen3.6-27B NVFP4, agentic replay | 10.216 output tok/s of wall | 12.59 tg128 | Different metric (end-to-end wall), engine and model. |
| Lin / llm-tracker | Llama-2-7B Q4_0 Vulkan pp512/tg128 | 881.71 / 52.22 | 1,366.27 / 54.16 (HIP) | May 2025 stack, TheBloke conversion. |
| kyuz0 toolboxes | Llama-2-7B Q4_0 pp512 | RADV 1337.70 · ROCm 7.2.3 1545.36 | 1,366.27 (HIP) | Newer ROCm; we are 12 % behind their ROCm figure. |
| Gufo (gufo-model-bench) | Qwen3.8-27B Q4 pp2048 d0 / tg128 d0 | 357.54 / 12.06 | 329.8 / 12.44 | Same engine and flags (matched rows). Ours pp is 92.2 % of theirs, tg 103.2 %. |
| Halogen | decode retention at 32k | gpt-oss-120b 92.6 % | 70.8 % (compare-external) | Closed engine. Shape only; absolute numbers blocked. |
| Level1Techs / AMD | Llama 3.1 70B 4.97 tok/s · Llama 4 Scout “up to 15” | — | not measured | No matching model cell. Context only. |
Reading. On llama-bench we land 3.5–4.3 % below the vendor’s prefill numbers for three of four models (HIP; gpt-oss-120b 14.4 %) and 9.4–28.7 % below its decode numbers. The vendor’s conditions are unstated, so this is a floor comparison and not a defect claim. Against reviewers using consumer front-ends (Ollama, LM Studio), our llama.cpp numbers are higher, as expected from the leaner engine. Against same-engine community references (Gufo), we match decode and trail prefill by about 8 %. Against newer ROCm toolboxes (kyuz0), we trail prefill by about 12 %. The gap tracks the software stack, not the box.
As a NAS. Every candidate pool reads well above what one 10GbE link carries (1.25 GB/s), so a single client will be network-bound on reads. In the post-cache write state, though, RAIDZ1 sequential write (0.718 GB/s cold, stage 1) is below 10GbE line rate. Sustained large ingest can therefore be drive-bound on this NM790 population. Network throughput itself was not measured in this campaign.
6 · Cross-test insights
- Drive write state outranks the filesystem. The same RAIDZ1 layout wrote 4.499 GB/s in STO-09 S1 (after a 50 % fill), 0.718 GB/s after full preconditioning (stage 1), and 1.178 GB/s (non-steady) in the one-hour soak. The no-failure control lost a third of S1 without any failure. Any write comparison on NM790s must state the drive state.
- SN5 at x4 is what makes the 5-wide layouts fast. Every 5-member parity layout reads 9.0 GB/s. The superseded 4-wide RAIDZ1 on four x1 members read 6.467 GB/s (RUN SUPERSEDED, comparison only).
- Link training is a silent failure mode. SN1 trained at Gen1 in six cells (#72) and again on 2026-09-29 (that AI run is excluded). A per-run link-speed gate is cheap insurance; see gaps.
- Warm reads hide layout. All six warm FS controls read 35.685–36.74 GB/s, the DRAM ceiling. Small-file copy (STO-06) converges at 0.418–0.724 GB/s across every cold layout. Neither separates layouts.
- AI and storage barely interact once loaded. Inference reads the model once. After that, the only storage-sensitive AI behaviour is cold load and streaming. Pick the pool on storage merits.
7 · Recommendations
Per workload
Per OS / stack
| Stack | Do | Avoid / note |
|---|---|---|
| Proxmox VE | ZFS RAIDZ1 (or RAID10 + RAIDZ1 split) for local-zfs. VM disks as zvols (16K volblocksize default; not A/B-tested here). Pass the iGPU to an LXC for llama.cpp, or run it on the host. | Check lspci -vv link speeds after every boot (SN1 downtrained twice). Separate pool for SATA bays. |
| TrueNAS SCALE | RAIDZ1 or RAIDZ2 pool. SMB/NFS datasets recordsize=1M for media and models, 16–64K for shares with small files. | AI apps run in containers; ROCm support on TrueNAS was not tested. No SLOG without PLP. |
| Fedora / Ubuntu | OpenZFS RAIDZ1 for data. Current ROCm or Mesa RADV for llama.cpp (newer stacks reach the community’s higher pp). Keep models on ZFS or btrfs; resident speed is identical. | If you choose btrfs, use raid1/raid10 profiles for data (raid1c3 metadata). mdadm raid5 suits bulk sequential only. |
8 · Buying guidance
- Buy it if you want one quiet box that serves files at 10GbE and runs 20–120B MoE models at interactive speed: gpt-oss-120b at 53.12 tok/s, Qwen3.5-122B at 22.97 tok/s.
- Do not expect NVMe-array sequential numbers beyond about 9 GB/s, or more than about 2 GB/s from any one of the four x1 slots. Small-block IO is unaffected.
- Drives: the NM790 is DRAM-less with no PLP, and its sustained write falls sharply after the SLC cache (§3.7). For write-heavy or sync-heavy use, prefer drives with DRAM and PLP, especially in the x4 slot.
- Dense models are bandwidth-bound: ours decodes Qwen3.8-27B Q4 at 12.59 tok/s; ServeTheHome reports ~9 tok/s for Qwen3.6 27B (FP8) and Level1Techs reports 4.97 tok/s for Llama 3.1 70B on this silicon. MoE models are where the box shines.
- Expect software to move results more than storage does: ROCm version, backend and engine shift pp by 10–25 %.
9 · Limitations & open questions
- Write-hole test (#59) not run; SLOG (#57) not run; KV-cache quantisation (#61) not run; prefill past 32k in stage 3 (#60) covered only by the Gufo rows to 131k; scheduling probe (#62) not run.
- Stage-6 STO-13 result lost (tmpfs). Only the post-campaign STO-13b exists, on a different OS image.
- SATA bays unmeasured. Network throughput unmeasured.
- Random IO across stacks is access-method-confounded (zvol vs file). No file-based ZFS random cell exists.
- RAIDZ1 cold mixed 70/30 is PROVISIONAL (19× spread). Stage 1 cell 5 (RAIDZ2 4-wide) is incomplete.
- Stage 7: the attended rebuild arm with per-member io_ticks, which the control decision asked for, has not run. Only two control replicates exist.
- Vendor floor conditions unknown. Vulkan vs HIP gaps (#46/#48) are characterised, not explained.
- The btrfs raid10 low cold read (3.616 GB/s) is unexplained.
- NM790 endurance (TBW consumed by the campaign) is not sealed.
Each of these is tracked as a follow-up in the lab’s private issue tracker.
10 · What changed since the 2026-09-18 review
| Topic | 2026-09-18 | Now (sealed) |
|---|---|---|
| mdadm raid5/6 cold seq read | 1.14 GB/s, HOLD (“8× slower”) | 9.035 GB/s after Gen4 reruns; the cause was SN1 at Gen1 (#72) |
| Fastest measured | btrfs raid5 (sole frontier) | Tie: btrfs raid5 9.034 / mdadm raid5 9.035 GB/s |
| Degraded / rebuild | no data | 8 arms + pilot + 2 controls; RAIDZ1 93.51 % degraded read vs btrfs raid5 5.87 % |
| ZFS vs btrfs write | btrfs raid5 writes ~5.7× RAIDZ1 | Confounded by drive state: in matched STO-09 S1, RAIDZ1 4.499 vs btrfs 2.78 GB/s |
| AI coverage | 4 provisional cells | 21 passed cells: HIP + Vulkan, streamed models, vendor-floor ratios, depth to 55k (131k via Gufo) |
| USB | missing | STO-13 lost; STO-13b post-campaign 905.6 / 376.2 MB/s |
| Write hole · SLOG | caveat · untested | unchanged: still not run |
A · Evidence tables
Run ids are timestamps of sealed result directories (appendix tables omit the 2026 year). Red = non-steady; grey = no steadiness verdict; ⚠ = PROVISIONAL. Full sealed precision is kept in the lab’s private metrics ledger.
| layout | members | TiB | seq R j1 GB/s | seq R j4 GB/s | seq W j1 GB/s | seq W j4 GB/s | r4K R IOPS | r4K W IOPS | r16K R IOPS | r16K W IOPS | mixed IOPS | sync IOPS | smallfiles GB/s | runs |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ZFS RAID10 · 4× x1 | 4×x1 | 6.71 | 6.219 | 7.024 | 0.638 | 0.894 | 115,855 | 40,740 | 51,676 | 51,195 | 104,485 | 1,675 | 0.521 | 09-13-15.49 |
| ZFS RAIDZ1 · 5-wide | 4×x1 + 1×x4 | 14.11 | 6.748 | 7.83 | 0.425 | 0.718 | 67,044 | 18,865 | 19,666 | 30,495 | 757 ⚠ | 415 | 0.534 | 09-13-17.14 |
| ZFS RAIDZ2 · 5-wide | 4×x1 + 1×x4 | 10.21 | 8.053 | 8.911 | 0.464 | 0.961 | 81,540 | 10,357 | 26,937 | 10,912 | 27,755 | 428 | 0.532 | 09-13-18.42 09-13-21.52 |
| btrfs raid10 · 4× x1 | 4×x1 | 6.99 | 3.601 | 3.616 | 1.95 | 2.372 | 555,448 | 91,074 | 153,304 | 35,553 | 88,085 | 2,153 | 0.519 | 09-14-05.18 09-26-00.17 |
| btrfs raid5 · 5-wide | 4×x1 + 1×x4 | 14.43 | 9.033 | 9.034 | 1.912 | 4.066 | 573,194 | 55,450 | 189,731 | 22,981 | 48,472 | 1,365 | 0.44 | 09-14-13.57 |
| btrfs raid6 · 5-wide | 4×x1 + 1×x4 | 10.71 | 9.025 | 9.026 | 1.465 | 2.72 | 573,937 | 43,316 | 215,280 | 22,066 | 44,116 | 1,183 | 0.418 | 09-14-17.56 |
| mdadm raid10 · 4× x1 | 4×x1 | 7.02 | 7.223 | 7.223 | 2.483 | 2.521 | 575,998 | 33,934 | 354,299 | 26,508 | 78,582 | 323 | 0.724 | 09-25-16.03 |
| mdadm raid5 · 5-wide | 4×x1 + 1×x4 | 14.41 | 9.034 | 9.035 | 4.411 | 5.04 | 530,451 | 72,598 | 89,454 | 2,489 | 106,552 | 934 | 0.71 | 09-25-18.53 |
| mdadm raid6 · 5-wide | 4×x1 + 1×x4 | 10.71 | 9.027 | 9.029 | 3.415 | 3.451 | 514,941 | 25,541 | 268,724 | 2,313 | 17,213 | 2,256 | 0.469 | 09-25-21.38 |
| ZFS RAID0 · control | 4×x1 + 1×x4 | 17.85 | 7.95 | 8.695 | 0.599 | 1.897 | 121,060 | 54,612 | 47,480 | 59,950 | 107,686 | 2,267 | 0.541 | 09-13-14.28 |
| single SN1 · x1 | SN1 @x1 | 3.0 | 1.782 | 1.8 | 0.615 | 0.641 | 35,116 | 14,114 | 13,875 | 16,762 | 22,478 | 1,283 | 0.461 | 09-13-13.00 |
| single SN5 · x4 | SN5 @x4 | 3.0 | 5.665 | 5.888 | 0.702 | 1.328 | 41,318 | 20,551 | 18,343 | 47,112 | 29,634 | 1,398 | 0.514 | 09-12-19.42 |
| ZFS RAID10 + spare | 4×x1 | 6.71 | 6.232 | 6.629 | 0.757 | 1.172 | 111,501 | 25,048 | 44,982 | 38,956 | 83,997 | 1,631 | 0.54 | 09-13-04.48 |
| ZFS mirror 2-way | 2×x1 | 3.19 | 3.377 | 3.455 | 0.635 | 0.747 | 71,094 | 17,632 | 32,099 | 20,693 | 51,891 | 1,094 | 0.557 | 09-12-05.05 09-12-17.37 09-12-22.05 |
| layout | members | TiB | seq R j1 GB/s | seq R j4 GB/s | seq W j1 GB/s | seq W j4 GB/s | r4K R IOPS | r4K W IOPS | r16K R IOPS | r16K W IOPS | mixed IOPS | sync IOPS | smallfiles GB/s | runs |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ZFS RAID10 | 4×x1 | 6.71 | 7.133 | 7.221 | 0.425 | 0.879 | 183,883 | 34,483 | 191,195 | 34,180 | 71,876 | 1,792 | 0.52 | 09-12-09.00 |
| ZFS RAIDZ1 5w | 4×x1 + 1×x4 | 14.11 | 7.252 | 8.215 | 0.483 | 0.664 | 100,690 | 26,464 | 78,651 | 32,929 ⚠ | 35,254 | 256 | 0.558 | 09-13-08.49 09-13-22.49 |
| ZFS RAIDZ2 5w | 4×x1 + 1×x4 | 10.21 | 9.022 | 9.028 | 0.366 | 0.943 | 122,097 | 25,213 | 83,469 | 19,022 | 18,157 | 368 | 0.562 | 09-13-10.13 09-13-22.26 |
| ZFS RAID0 | 4×x1 + 1×x4 | 17.85 | 9.013 | 8.979 | 0.618 | 2.002 | 185,497 | 52,320 | 168,814 | 67,998 | 102,521 | 2,243 | 0.576 | 09-13-07.30 |
| ZFS RAID10 + spare | 4×x1 | 6.71 | 7.134 | 7.222 | 0.854 | 1.14 | 166,324 | 32,942 | 173,687 | 29,288 | 69,147 | 1,699 | 0.514 | 09-13-11.37 |
| ZFS mirror 2-way | 2×x1 | 3.01 | 3.611 | 3.611 | 0.511 | 0.552 | 127,647 | 16,285 | 127,455 | 14,916 | 32,438 | 1,250 | 0.554 | 09-12-12.50 |
| single x1 | SN1 @x1 | 3.0 | 1.808 | 1.808 | 0.705 | 0.934 | 62,656 | 22,869 | 63,139 | 22,276 | 35,945 | 1,279 | 0.572 | 09-12-06.23 |
| single x4 | SN5 @x4 | 3.0 | 6.149 | 6.201 | 1.201 | 1.44 | 68,879 | 23,649 | 68,522 | 40,735 | 41,130 | 1,337 | 0.552 | 09-13-06.11 |
| layout | members | TiB | seq R j1 GB/s | seq R j4 GB/s | seq W j1 GB/s | seq W j4 GB/s | r4K R IOPS | r4K W IOPS | r16K R IOPS | r16K W IOPS | mixed IOPS | sync IOPS | smallfiles GB/s | runs |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| btrfs raid10 | 4×x1 | 7.42 | 30.606 | 35.685 | 2.381 | 12.109 | 4,371,901 | 163,146 | 2,416,415 | 156,718 | 537,308 | 3,507 | 0.588 | 09-14-12.44 |
| btrfs raid5 | 4×x1 + 1×x4 | 14.87 | 29.893 | 36.272 | 2.984 | 3.265 | 4,319,328 | 74,417 | 2,420,503 | 86,081 | 194,837 | 3,112 | 0.494 | 09-14-16.40 |
| btrfs raid6 | 4×x1 + 1×x4 | 11.15 | 29.682 | 35.706 | 2.619 | 2.767 | 4,362,546 | 8,744 | 2,417,784 | 9,310 | 28,002 | 1,607 | 0.19 | 09-14-19.15 |
| mdadm raid10 | 4×x1 | 7.37 | 30.266 | 36.74 | 11.703 | 10.923 | 4,350,998 | 66,697 | 2,396,829 | 63,234 | 201,017 | 325 | 0.785 | 09-25-17.29 |
| mdadm raid5 | 4×x1 + 1×x4 | 14.76 | 30.789 | 35.941 | 11.257 | 10.93 | 4,392,225 | 99,321 | 2,403,942 | 79,364 | 250,191 | 664 | 0.66 | 09-25-20.14 |
| mdadm raid6 | 4×x1 + 1×x4 | 11.07 | 31.36 | 36.714 | 12.641 | 10.12 | 4,311,695 | 145,638 | 2,413,874 | 137,587 | 473,307 | 800 | 0.697 | 09-25-23.00 |
| arm | victim | rebuild s | rebuild GB/s | S1 seq R GB/s | S2 seq R % | S4 seq R % | S1 seq W GB/s | S2 seq W % | S4 seq W % | verdict |
|---|---|---|---|---|---|---|---|---|---|---|
| ZFS RAIDZ1 | SN2 | 1740.0 | 1.1656 | 7.434 | 93.51 | 102.81 | 4.499 | 64.28 | 39.32 | FAIL |
| ZFS RAIDZ1 · loaded | SN2 | 1550.0 | 1.3828 | 7.129 | 97.11 | 102.88 | 4.43 | 73.88 | 47.04 | FAIL |
| ZFS RAIDZ2 | SN2 | 1690.0 | 1.186 | 8.865 | 59.55 | 101.76 | 3.133 | 78.65 | 46.95 | FAIL |
| btrfs raid10 | SN2 | 2790.0 | 0.7316 | 4.432 | 71.19 | 112.7 | 2.316 | 91.41 | 92.75 | PASS |
| btrfs raid5 | SN2 | 3720.0 | 0.5498 | 9.045 | 5.87 | 95.26 | 2.78 | 98.03 | 109.28 | PASS |
| btrfs raid5 · loaded | SN2 | 3480.0 | 0.6163 | 9.044 | 5.87 | 93.17 | 2.657 | 100.26 | 86.04 | FAIL |
| btrfs raid5 · x4 victim | SN5 | 2590.0 | 0.7891 | 9.045 | 5.86 | 94.78 | 2.863 | 106.53 | 75.45 | FAIL |
| btrfs raid6 | SN2 | 6380.0 | 0.3207 | 9.042 | 5.86 | 96.0 | 1.968 | 117.94 | 32.67 | FAIL |
| no-failure control · run 2026-09-25-11.29 | — | — | — | 7.622 | 97.55 | 99.51 | 4.24 | 66.67 | 66.58 | S4/S2 0.9986 |
| no-failure control · run 2026-09-26-00.58 | — | — | — | 7.409 | 103.14 | 98.65 | 4.397 | 66.59 | 67.71 | S4/S2 1.0167 |
| model | backend | ours pp512 | floor pp512 | ratio | ours tg128 | floor tg128 | ratio | run |
|---|---|---|---|---|---|---|---|---|
| gpt-oss-20b | HIP | 1,514.00 | 1575.75 | 0.9608 | 75.31 | 83.09 | 0.9064 | 2026-09-23-13.05 |
| gpt-oss-20b | Vulkan | 1,408.84 | 1575.75 | 0.8941 | 80.72 | 83.09 | 0.9715 | 2026-09-23-07.05 |
| Gemma 4 26B-A4B | HIP | 1,148.97 | 1200.58 | 0.957 | 50.13 | 70.33 | 0.7128 | 2026-09-22-06.02 |
| Gemma 4 26B-A4B | Vulkan | 1,102.47 | 1200.58 | 0.9183 | 55.50 | 70.33 | 0.7892 | 2026-09-22-15.58 |
| gpt-oss-120b | HIP | 572.64 | 668.79 | 0.8562 | 53.23 | 59.3 | 0.8976 | 2026-09-23-15.03 |
| gpt-oss-120b | Vulkan | 551.75 | 668.79 | 0.825 | 57.33 | 59.3 | 0.9668 | 2026-09-23-08.23 |
| Qwen3.5-122B-A10B | HIP | 306.34 | 317.58 | 0.9646 | 23.03 | 31.76 | 0.7252 | 2026-09-22-10.11 |
| Qwen3.5-122B-A10B | Vulkan | 283.08 | 317.58 | 0.8914 | 24.47 | 31.76 | 0.7705 | 2026-09-23-00.06 |
| model | backend | pool | cold load s | pp512 tok/s | tg128 tok/s | pp @32k tok/s | tg @55k tok/s | run |
|---|---|---|---|---|---|---|---|---|
| Qwen3-0.6B Q8 (smoke) | HIP | btrfs raid5 · cold | 2.025 | 11434.47435 | 229.529638 | 2745.061274 | — | 2026-09-22-05.43 |
| Qwen3-0.6B Q8 (smoke) | HIP | ZFS RAIDZ1 · pc=all, ARC cold | 3.072 | 11585.991494 | 229.846661 | 2777.739635 | — | 2026-09-23-16.11 |
| Llama-2-7B Q4_0 | HIP | btrfs raid5 · cold | 2.025 | 1366.272992 | 54.158066 | 432.078239 | — | 2026-09-29-01.31 |
| gpt-oss-20b MXFP4 | HIP | btrfs raid5 · cold | 5.04 | 1488.023566 | 75.491938 | 1071.686866 | 45.28471 | 2026-09-23-13.05 |
| gpt-oss-20b MXFP4 | Vulkan | btrfs raid5 · cold | 6.761 | 1408.366322 | 80.697347 | 790.282376 | 53.880727 | 2026-09-23-07.05 |
| Gemma 4 26B-A4B Q4_K_M | HIP | btrfs raid5 · cold | 5.035 | 1130.874349 | 50.146229 | 733.241665 | 37.31528 | 2026-09-22-06.02 |
| Gemma 4 26B-A4B Q4_K_M | HIP | ZFS RAIDZ1 · pc=all, ARC cold | 6.758 | 1136.82361 | 50.079649 | 721.198722 | 37.280024 | 2026-09-23-04.57 |
| Gemma 4 26B-A4B Q4_K_M | Vulkan | btrfs raid5 · cold | 10.654 | 1093.213531 | 55.40021 | 730.436897 | 39.273202 | 2026-09-22-15.58 |
| Qwen3.8-27B Q4_K_XL | HIP | btrfs raid5 · cold | 4.635 | 332.939424 | 12.589999 | 278.517628 | 10.553017 | 2026-09-29-18.07 |
| Qwen3.8-27B Q8_K_XL | HIP | btrfs raid5 · cold | 6.782 | — | — | — | — | 2026-09-29-09.55 |
| gpt-oss-120b MXFP4 | HIP | btrfs raid5 · cold | 11.256 | 564.012211 | 53.116634 | 457.81774 | 31.240673 | 2026-09-23-15.03 |
| gpt-oss-120b MXFP4 | Vulkan | btrfs raid5 · cold | 49.375 | 548.470986 | 57.253699 | 373.161288 | 37.666248 | 2026-09-23-08.23 |
| Qwen3.5-122B-A10B Q4_K_M | HIP | btrfs raid5 · cold | 12.111 | 308.208797 | 22.969954 | 264.913976 | 19.943198 | 2026-09-22-10.11 |
| Qwen3.5-122B-A10B Q4_K_M | Vulkan | btrfs raid5 · cold | 63.25 | 279.392725 | 24.455856 | 229.577776 | 21.093569 | 2026-09-23-00.06 |
| DeepSeek V4 Flash IQ2_XXS | HIP | btrfs raid5 · cold | 13.65 | 27.353744 | 15.261516 | — | — | 2026-09-29-16.41 |
| DeepSeek V3.1 Q2_K_XL (streamed) | HIP | btrfs raid5 · cold | 5.122 | 14.67113796370338 | 1.782020828368677 | — | — | 2026-09-29-15.17 |
| DeepSeek V3.1 Q2_K_XL (streamed) | HIP | ZFS RAIDZ1 · pc=all, ARC cold | 6.556 | 13.500959553793148 | 1.4079943045119931 | — | — | 2026-09-29-05.00 |
| Kimi K2 Thinking IQ1 (streamed) | HIP | btrfs raid5 · cold | 38.334 | 3.569684 | 1.093135 | — | — | 2026-09-29-03.21 |
| Kimi K2 Thinking IQ1 (streamed) | HIP | ZFS RAIDZ1 · pc=all, ARC cold | 181.147 | 4.688261 | 1.548387 | — | — | 2026-09-29-13.35 |