18 min read

The "Core Lab" Monster: My 80+TB DIY NAS Build (2026)

Forget off-the-shelf simplicity. Explore the architecture of a 17-drive, 80TB+ DIY NAS. From enterprise SAS hardware to ZFS pool optimization, this is the blueprint for a "forever" server built for maximum data density and local ownership.
A picture of Core Lab Custom Server/NAS while being built, on a floor beside oragizer bin, with drive cables hanging out and side, top panels removed.
Core Lab Custom Server/NAS while being built.

What started in 2012 as some spare hard drives thrown into an old gaming PC has evolved into... this.

Meet the current heart of Core Lab. It is a consolidation beast—one machine designed to replace two older servers and a Synology NAS. It strikes the perfect balance between cost and performance, handling everything from 4K Transcoding to LLM AI inference, all while serving 80TB+ of storage to my network.

In this build log, I’ll break down exactly why I chose these parts, the failures I encountered along the way (RIP ASUS Motherboard), and how you can build a similar monster without breaking the bank.

This post is part of my DIY custom NAS/Server Series:


The Mission: Consolidation

I was tired of running multiple loud, power-hungry Enterprise servers (looking at you, Dell T610). I wanted one system that could do it all:

  • NAS: 80TB+ of reliable ZFS storage.
  • Media Server: Plex/Jellyfin with hardware transcoding.
  • Docker Host: Running 50+ containers (The *Arrs, Home Assistant, etc.).
  • AI Lab: Enough GPU power for local LLM tinkering.

The Component Breakdown

Warning: This is not a "Budget" build, but it is a "Value" build. almost every part was bought used, on sale, or repurposed.

1. The Case: Fractal Design Define 7 XL

Verdict: The Greatest NAS Case Ever Made. I cannot emphasize this enough: If you are building a storage server, buy this case.

  • Capacity: It swallows up to 18-20 3.5" Hard Drives (Storage Layout).
  • Flexibility: Fits everything from Mini-ITX to E-ATX Server boards.
  • Silence: It is dead quiet, sitting happily in my rack without sounding like a jet engine.
💡 Core Lab Tip: If you buy this case, you must buy the extra HDD trays (Type-B). It only comes with a few; you'll need to buy the rest to fill it up.

Housing 18 drives silently without resorting to a loud, power-hungry datacenter rack is an engineering challenge in itself. For a deep dive into the acoustics, thermal modifications, and static-pressure fan layouts I used to keep this array ice-cold, read my Long-Term Fractal Design Define 7 XL Review.

Fractal 7 XL Review

2. The Brains: Ryzen 5 3700X + MSI X570

I went with the Ryzen 3700X (8 Cores / 16 Threads). It’s an older chip now, but for a server, it is a powerhouse. It idles relatively low but screams when I need to compile code or process video.

🚧
⚠️ The Motherboard Nightmare (Read this!) I originally built this with an ASUS TUF X570. It was a disaster. It refused to boot with my SAS HBA card and had endless RAM compatibility issues. I swapped it for an MSI X570-A PRO, and it worked instantly.
  • Why X570? It provides PCIe Gen 4 lanes.
  • The Trade-off: The secondary PCIe x16 slot runs at x4 speed. This limits bandwidth slightly for expansion cards, but for a home server, it is negligible.

3. The RAM: 64GB DDR4 (Non-ECC)

Wait, no ECC RAM for ZFS? I tried! I bought unbuffered ECC RAM. The motherboard rejected it... I tried different slots, BIOS settings, you name it. After hours of research, I decided that for a home media server, the risk of a "bit flip" corrupting a movie file is statistically lower than the headache of finding compatible ECC parts. 64GB allows ZFS to cache heavily in RAM, making the system feel snappy. VERY snappy - more about that below...

The "Reality Check": Do You Need ECC?

You will hear people scream that running ZFS without ECC RAM is suicidal. They claim that a "cosmic ray" will flip a bit during a scrub and ZFS will "correct" your good data with bad data, destroying your pool. This is largely a myth.

🚀 The "Bit Flip" Stats (Google's Data) A massive study by Google on their server fleet found that while memory errors do happen, they are mostly due to hard hardware faults (bad sticks), not random cosmic rays.The Stat: Google found that only ~8% of DIMMs experienced a correctable error per year.The Implication: If your RAM is healthy (test it with MemTest86!), the odds of a random bit flip hitting exactly the wrong metadata block at the exact moment of a write are infinitesimally small.The Verdict: ZFS without ECC is still safer than NTFS or EXT4 with ECC. Why? Because ZFS at least knows when data is corrupted (via checksums). Other filesystems just silently serve you the corrupted file.

My Advice: Buy standard RAM, run a 24-hour MemTest86 pass, and sleep easy. For a home media server, you don't need to pay the "ECC Tax."

4. The Boot Drive: 128GB SATA SSD

Wait, why not NVMe? I originally bought a fast NVMe drive for this build, but I quickly realized a problem: PCIe Lanes.

  • The Constraint: My GPU uses x16 lanes (or x8/x8 split), and my LSI HBA card needs x8 lanes. On a consumer platform like AM4, PCIe lanes are precious gold.
  • The Solution: I used a standard 2.5" SATA SSD connected to the motherboard's SATA port. That and I already owned it, no cost.
  • The Result: OpenMediaVault loads in seconds, and my Docker containers feel snappy. An NVMe drive would have been overkill for a simple OS drive and would have stolen bandwidth from my HBA or GPU.
    • I am going to be making an upgrade and change soon regarding this!

5. Storage: The "Spinning Rust"

This is the star of the show.

  • The Boot Drive: A simple 128GB SATA SSD (Old reliable).
  • The Array: 12x Seagate Enterprise SAS drives (6TB).
  • The Deal: I found these brand new (old stock) on a Facebook group for $35 USD each.

Why SAS? SAS drives are enterprise-grade. They are built to run 24/7 for a decade. However, you cannot plug them into a normal motherboard SATA port. You need an HBA (Host Bus Adapter).

  • My HBA: LSI MegaRAID 9300-16i (IT Mode). This allows the OS (OpenMediaVault) to see every drive individually, which is required for ZFS.

📸 The Build Log: Step-by-Step

1. The "Scrap Lab" Gold (Shucking the Drives)

I scored these 6TB SAS drives for $35/each because they were surplus stock for a SAN storage array. They arrived locked inside proprietary plastic caddies.

⚠️ CRITICAL WARNING: The "3.3V Pin" Issue‼️

If you buy Enterprise SAS/SATA drives, they might not spin up. When I first plugged these drives in, nothing happened. Dead silence.

The Problem: Modern enterprise drives utilize the 3.3V pin on the SATA power connector for a feature called "Power Disable" (a remote reset function). Consumer Power Supplies (like my Corsair 1050W) blindly send 3.3V power to this pin. When the drive detects voltage there, it thinks you are holding down the "Reset" button, so it never spins up.

The "Core Lab" Fix: You have two options to fix this. I went with the permanent solution:

  1. The Kapton Tape Method: You can carefully cover the first 3 pins of the drive's power connector with non-conductive Kapton tape. This is tedious, delicate, and I did not have any of this material on hand.
  2. The "Wire Cutter" Method (My Choice): Since I am using dedicated SATA power cables for these drives, I simply cut the 3.3V wire (usually the Orange wire) on the PSU's SATA cable. Mine were all black so I had to ensure I had the correct cable, which is the one closest to the "L" shape on the connector. I snipped it and covered the ends with electrical tape!

Do the one that's first in the line from the PSU, this way you get the entire line of power cables!

    • Result: The drive gets 12V and 5V (which it needs) but zero 3.3V (which keeps it awake).
SATA power cable with the 3.3V orange wire cut to fix the Power Disable feature on enterprise hard drives.
The "Hack" in action. By snipping the 3.3V line (Orange), the Enterprise drives finally spun to life. Do this at your own risk!

2. The Foundation (Motherboard & CPU)

The MSI X570-A PRO gives me the PCIe Gen 4 lanes I need.

3. Cooling the Beast (No AIOs Here!)

For a server that runs 24/7, I trust air cooling over liquid. AIO pumps eventually die; blocks of metal do not.

4. The Secret Weapon: The LSI HBA Card

This is how you connect 16 Enterprise drives to a consumer motherboard.

LSI 9300-16i HBA card for connecting SAS drives to a consumer motherboard in IT mode.
The LSI 9300-16i (IT Mode). This card bypasses the motherboard's limitations and passes the SAS drives directly to the OS, which is critical for ZFS stability.

5. Mass Storage (The Array)

Once shucked, the drives slide perfectly into the Fractal trays.

6. The "PCIe Tetris" Hack (10Gbps on an x1 Slot)

This is where the MSI X570's consumer roots started to hurt. I had a GPU in the top slot and the LSI HBA in the bottom x4 slot. I physically had no room left for my Dual 10Gbps Intel NIC. The Solution: A StarTech x1 to x16 Adapter.

Dual port Intel 10Gbps NIC mounted in a StarTech x1 to x16 PCIe adapter riser to fit in a consumer motherboard.
The PCIe Lane Hack: This simple StarTech adapter allows me to plug a full-sized enterprise network card into a tiny x1 PCIe slot.

The Trade-off: This Intel NIC normally wants an x8 slot. By forcing it into an x1 slot, I am technically strangling its bandwidth.

  • Theoretical Max: PCIe 3.0 x1 caps out around ~1GB/s (8Gbps).
  • Reality: I can't hit the full dual 20Gbps potential of the card, but for a home server, getting ~8Gbps is still light years faster than standard Gigabit Ethernet. It works perfectly for my needs.

My Beloved Case Choice: Fractal Design Define 7 XL!

I cannot go on enough about how amazing the Fractal Design Define 7 XL case is! I'll literally never be buying another NAS / server case again. Absolutely wild how flexible and wonderful it is to build with.

Dust covers removed, fan installs.webp

It may not be pretty to some, but when it was going to be sitting under my network rack in my back storage room, who cares? I needed maximum functionality and ability out of it! You can install up to 20, yes 20 3.5inch drives!

Fractal Define 7 XL bare.webp

That said, why I chose it broken down -

  • Seemingly perfectly for what I had in mind: One server to do my storage & plex & dockers (entire tech stack) in an incredibly flexible case & layout.
  • Strong Online reviews - Linux Tech Tips, Hardware Canucks, Reddit...
  • Can hold up to 20 3.5" drives! in "storage" configuration.
  • Can fit any motherboard from E-ATX (Xlarge like server mobo) through to mini-itx!
  • Flexibility for upgrades later, whichever way/size/shape I chose.
  • Cable management, fan placement options, ease of use and most importantly, cooling capability. Lastly for me was noise / silent operation.

If you go with a Fractal case, you'll need these drive trays!

Fractal Design Hard Drive Tray Kit – Type B for Define 7 and Meshify 2 Series - Black (2-Pack) : Amazon.ca: Electronics
Fractal Design Hard Drive Tray Kit – Type B for Define 7 and Meshify 2 Series - Black (2-Pack) : Amazon.ca: Electronics

Those beautiful blacked out fans in the front?👇

Arctic P12 Pro PST 120mm Case Fans

This is my favourite case fan and natural go to. I have them in my workstation and in my server, plus in my kids PCs. It's incredibly well built for being so cheap, it's like they cheated on materials design or something!

→ Check it on Amazon ⭐ 4.5


📊 Performance: How Fast is it?

I ran fio to stress-test the ZFS pool. Here is the result of reading a 4GB file with a queue depth of 64 (simulating heavy load).

The Benchmark Result:

  • Read Speed: ~3,409 MB/s (Sequential)
    • 3,409 MB/s ≈ 27.3 Gbps
    • The Math: 3409 * 8 (bits) = 27,272 Mbps -> 27.27 Gbps.
In fact, my drive array is nearly 3x faster than a 10Gbps network. I could technically feed two 10Gbps clients at full speed simultaneously and still have overhead left...
  • IOPS: ~208k
  • Latency: ~4.5ms
🚀
The "Secret Sauce": Understanding ZFS ARC
You might be looking at 208k IOPS and thinking, "That's impossible. Mechanical hard drives only do ~150 IOPS. Did the benchmark break?"
It didn't break. It demonstrated the magic of ZFS ARC (Adaptive Replacement Cache).
The "Library" Analogy:
Standard RAID: Every time you ask for a file, the system has to walk all the way to the back of the library (the hard drives), find the book, and walk it back to the front desk. This is slow.
ZFS ARC: ZFS realizes you might need that book again, so it leaves it on the front desk (RAM). When you ask for it, the librarian hands it to you instantly.
Why My Benchmark Was So Fast: I have 64GB of RAM in this server. My benchmark test file was only 4GB. ZFS saw that the entire test file could fit into the RAM cache. So, instead of reading from the spinning rust, it read directly from the memory chips.
Real-World Benefit: Is this "cheating"? No. This is exactly how you want a NAS to behave! In the real world, this means your Plex library thumbnails, recent documents, and directory lists load instantly because they live in RAM. The hard drives only wake up when you pull a massive, rarely accessed movie file.
The Lesson: Don't skimp on RAM for your NAS. It turns a sluggish archive into a lightning-fast server.
Translation: This thing saturates my 10Gbps network link without breaking a sweat. Whether it's 5 people streaming Plex or me moving a 50GB backup file, the drives are never the bottleneck.

Detailed Field Report (FIO Output)

I ran a test with fio, reading a 4Gb 4k block size file. And this is with the ZFS array slightly bottlenecked due to my PCIe lane issue, and running my workload of Plex & 58 dockers! Result at very bottom...

root@codex:/# fio --name=seq_read --rw=read --bs=4k --size=4G --filename=/brain/DOCKERS/fio_test --direct=1 --iodepth=64 --numjobs=4
seq_read: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=64
...
fio-3.33
Starting 4 processes
seq_read: Laying out IO file (1 file / 4096MiB)
note: both iodepth >= 1 and synchronous I/O engine are selected, queue depth will be capped at 1
note: both iodepth >= 1 and synchronous I/O engine are selected, queue depth will be capped at 1
note: both iodepth >= 1 and synchronous I/O engine are selected, queue depth will be capped at 1
note: both iodepth >= 1 and synchronous I/O engine are selected, queue depth will be capped at 1
Jobs: 4 (f=4): [R(4)][100.0%][r=3691MiB/s][r=945k IOPS][eta 00m:00s]
seq_read: (groupid=0, jobs=1): err= 0: pid=610309: Fri Aug 15 14:03:24 2025
read: IOPS=209k, BW=816MiB/s (856MB/s)(4096MiB/5020msec)
clat (usec): min=2, max=2693, avg= 4.51, stdev= 4.76
lat (usec): min=2, max=2693, avg= 4.55, stdev= 4.76
clat percentiles (nsec):
| 1.00th=[ 2928], 5.00th=[ 3120], 10.00th=[ 3280], 20.00th=[ 3472],
| 30.00th=[ 3664], 40.00th=[ 3824], 50.00th=[ 4016], 60.00th=[ 4256],
| 70.00th=[ 4576], 80.00th=[ 4960], 90.00th=[ 5600], 95.00th=[ 6240],
| 99.00th=[17280], 99.50th=[23424], 99.90th=[36096], 99.95th=[43264],
| 99.99th=[70144]
bw ( KiB/s): min=729304, max=991544, per=25.10%, avg=835712.00, stdev=98751.54, samples=10
iops : min=182326, max=247886, avg=208928.20, stdev=24688.13, samples=10
lat (usec) : 4=48.71%, 10=49.76%, 20=0.73%, 50=0.78%, 100=0.02%
lat (usec) : 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
lat (msec) : 2=0.01%, 4=0.01%
cpu : usr=9.98%, sys=87.55%, ctx=8104, majf=0, minf=12
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=1048576,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=64
seq_read: (groupid=0, jobs=1): err= 0: pid=610310: Fri Aug 15 14:03:24 2025
read: IOPS=209k, BW=816MiB/s (855MB/s)(4096MiB/5022msec)
clat (usec): min=2, max=963, avg= 4.52, stdev= 3.43
lat (usec): min=2, max=963, avg= 4.56, stdev= 3.43
clat percentiles (nsec):
| 1.00th=[ 2928], 5.00th=[ 3120], 10.00th=[ 3248], 20.00th=[ 3472],
| 30.00th=[ 3632], 40.00th=[ 3824], 50.00th=[ 4016], 60.00th=[ 4256],
| 70.00th=[ 4576], 80.00th=[ 4960], 90.00th=[ 5600], 95.00th=[ 6304],
| 99.00th=[18304], 99.50th=[23680], 99.90th=[36096], 99.95th=[43264],
| 99.99th=[68096]
bw ( KiB/s): min=729576, max=999104, per=25.09%, avg=835520.00, stdev=99702.78, samples=10
iops : min=182394, max=249776, avg=208880.00, stdev=24925.70, samples=10
lat (usec) : 4=49.17%, 10=49.20%, 20=0.76%, 50=0.84%, 100=0.02%
lat (usec) : 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
cpu : usr=8.34%, sys=89.29%, ctx=8511, majf=0, minf=12
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=1048576,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=64
seq_read: (groupid=0, jobs=1): err= 0: pid=610311: Fri Aug 15 14:03:24 2025
read: IOPS=208k, BW=813MiB/s (852MB/s)(4096MiB/5039msec)
clat (usec): min=2, max=3226, avg= 4.53, stdev= 5.71
lat (usec): min=2, max=3226, avg= 4.57, stdev= 5.71
clat percentiles (nsec):
| 1.00th=[ 2896], 5.00th=[ 3088], 10.00th=[ 3248], 20.00th=[ 3472],
| 30.00th=[ 3632], 40.00th=[ 3824], 50.00th=[ 4016], 60.00th=[ 4320],
| 70.00th=[ 4640], 80.00th=[ 5024], 90.00th=[ 5600], 95.00th=[ 6368],
| 99.00th=[17280], 99.50th=[23424], 99.90th=[36096], 99.95th=[43264],
| 99.99th=[73216]
bw ( KiB/s): min=729256, max=986368, per=24.97%, avg=831448.80, stdev=94785.38, samples=10
iops : min=182314, max=246592, avg=207862.20, stdev=23696.34, samples=10
lat (usec) : 4=48.47%, 10=49.98%, 20=0.74%, 50=0.78%, 100=0.02%
lat (usec) : 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
lat (msec) : 4=0.01%
cpu : usr=8.93%, sys=88.59%, ctx=7949, majf=0, minf=11
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=1048576,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=64
seq_read: (groupid=0, jobs=1): err= 0: pid=610312: Fri Aug 15 14:03:24 2025
read: IOPS=208k, BW=814MiB/s (854MB/s)(4096MiB/5032msec)
clat (usec): min=2, max=1758, avg= 4.53, stdev= 3.81
lat (usec): min=2, max=1758, avg= 4.57, stdev= 3.81
clat percentiles (nsec):
| 1.00th=[ 2896], 5.00th=[ 3088], 10.00th=[ 3248], 20.00th=[ 3472],
| 30.00th=[ 3632], 40.00th=[ 3824], 50.00th=[ 4016], 60.00th=[ 4320],
| 70.00th=[ 4640], 80.00th=[ 5024], 90.00th=[ 5664], 95.00th=[ 6368],
| 99.00th=[17280], 99.50th=[23424], 99.90th=[35584], 99.95th=[42752],
| 99.99th=[67072]
bw ( KiB/s): min=729320, max=994056, per=25.04%, avg=833692.80, stdev=98700.76, samples=10
iops : min=182330, max=248514, avg=208423.20, stdev=24675.19, samples=10
lat (usec) : 4=48.37%, 10=50.10%, 20=0.73%, 50=0.78%, 100=0.02%
lat (usec) : 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
lat (msec) : 2=0.01%
cpu : usr=9.02%, sys=88.69%, ctx=7674, majf=0, minf=12
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=1048576,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=64

Run status group 0 (all jobs):
READ: bw=3251MiB/s (3409MB/s), 813MiB/s-816MiB/s (852MB/s-856MB/s), io=16.0GiB (17.2GB), run=5020-5039msec


🛠 The "Core Lab" Monster Specs (2024 Build)

Note: This is the exact list of what I used. Some parts (like the CPU) are older generations now. For my current 2026 recommendations, scroll to the bottom.

ComponentMy PickWhy I Chose It
CaseFractal Design Define 7 XLThe King of NAS cases. Fits 18+ drives and is dead silent.
CPUAMD Ryzen 5 3700X8 Cores / 16 Threads. Repurposed from an old gaming rig. Plenty of power for Docker + Plex.
MotherboardMSI X570-A PROChosen for stability and PCIe Gen 4 support. (Replaced the ASUS TUF that failed to boot with HBA).
RAM64GB DDR4 (3200MHz)Non-ECC. High capacity allows ZFS to cache files in RAM for 200k+ IOPS speed.
GPUNVIDIA RTX 3060 12GBThe VRAM sweet spot for local AI/LLM experiments and handles unlimited hardware transcode streams.
HBA CardLSI 9300-16i (IT Mode)Essential for connecting 16 SAS drives to a consumer motherboard. Bypasses RAID to let ZFS manage the disks.
Boot Drive128GB SATA SSDSimple and reliable. Used SATA instead of NVMe to save precious PCIe lanes for the HBA & GPU.
NetworkDual Intel 10Gbps NICEnterprise-grade networking. (Mounted via a StarTech x1 Adapter to fit in the bottom slot).
Storage12x Seagate 6TB SASEnterprise surplus drives ($35/each). Required the "3.3V Pin Mod" to spin up.
Power SupplyCorsair 1050WOverkill? Maybe. But it handles the spin-up current of 12 enterprise drives without flinching.

With this guy built, and OS setup OMV8 wise, I could finally retire these two old dogs (power hungry!) and a Synology NAS!

📅 Want to Build This in 2026?

Hardware moves fast. While my Ryzen 3700X is still a beast, buying one new today doesn't make sense.

If you want to build a modern version of this monster (using current-gen CPUs, DDR5, and widely available parts), I have curated multiple updated parts lists for 2026.