Expanding AI Model Storage Space on the Cheap with bcache, a Small NVMe and a Used SATA Disk
A 1TB NVMe starts at around £100. A 4TB NVMe starts at £400+. A used 4TB 3.5" SATA disk is £80-90 on eBay. With bcache, you can put the NVMe in front of the SATA disk as a transparent read cache - your actively used data is served at NVMe speed, the rest sits on cheap bulk storage. You get 4TB of usable space with NVMe-class performance for hot data, for roughly a third of the cost of an equivalent NVMe.
This post covers setting up bcache on Fedora to cache a 4TB SATA HDD with a 1TB NVMe SSD for AI model storage.
The Disks
- Cache device: CT1000P310SSD2 1TB NVMe (
/dev/nvme0n1) - the fast, small disk - Backing device: Hitachi HDS72404 4TB 3.5" SATA (
/dev/sda) - the slow, large disk
The NVMe doesn't need to be large. Its job is to hold whatever data you're actively reading - in this case, whichever HuggingFace models you're currently loading for inference. A 1TB cache comfortably holds several large models. When you switch to a different model, the cache fills with the new data and the old data is evicted. First load is at SATA speed (~150-200 MB/s). Every subsequent load comes from the NVMe.
How bcache Works
bcache is a Linux kernel block layer cache. It sits between the filesystem and the raw block devices, presenting a single device (/dev/bcache0) with the full capacity of the SATA disk. Reads hit the NVMe cache first. If the data is there (cache hit), it's served at NVMe speed. If not (cache miss), it's read from the SATA disk and copied into the cache for next time.
In writethrough mode (the default used here), writes go directly to the SATA disk. The NVMe only holds read cache copies. If the NVMe dies, all data is still on the SATA disk. No data loss.
Setup
Install bcache-tools and wipe both disks:
sudo dnf install bcache-tools
sudo wipefs -a /dev/sda
sudo wipefs -a /dev/nvme0n1
Create both devices together in a single command. Creating them separately produces different Set UUIDs and the attach will fail:
sudo make-bcache -B /dev/sda -C /dev/nvme0n1
-B is the backing (slow) device. -C is the cache (fast) device. The output confirms both share the same Set UUID:
Name /dev/nvme0n1
Type cache
Set UUID: 04d7d814-56cb-49ec-b190-fe633b1bb1e3
...
Name /dev/sda
Type data
Set UUID: 04d7d814-56cb-49ec-b190-fe633b1bb1e3
...
Set the cache mode, format, and mount:
echo writethrough | sudo tee /sys/block/bcache0/bcache/cache_mode
sudo mkfs.ext4 /dev/bcache0
sudo mkdir -p /mnt/data
sudo mount /dev/bcache0 /mnt/data
Verify:
cat /sys/block/bcache0/bcache/state
# Should print: clean
Persistence Across Reboots
bcache writes metadata to both disks. The kernel detects the bcache superblocks on boot and reassembles the device automatically. The cache stays warm - previously cached data persists on the NVMe across reboots.
Add the mount to fstab:
BCACHE_UUID=$(sudo blkid -s UUID -o value /dev/bcache0)
echo "UUID=$BCACHE_UUID /mnt/data ext4 defaults 0 2" | sudo tee -a /etc/fstab
If bcache ever fails to load on boot, add the module explicitly:
echo bcache | sudo tee /etc/modules-load.d/bcache.conf
Writethrough vs Writeback
| Mode | Writes go to | Read cache | Data safe if NVMe dies |
|---|---|---|---|
| writethrough | SATA disk directly | Yes | Yes |
| writeback | NVMe first | Yes | No (dirty data lost) |
Writethrough is the safe default. For model files that can be re-downloaded, writeback is a reasonable trade - faster writes, with the only risk being a re-download if the NVMe fails:
echo writeback | sudo tee /sys/block/bcache0/bcache/cache_mode
Done
Once mounted, /mnt/data is a standard filesystem. The first load of a model into VRAM is also at SATA speed. Every subsequent load of the same model is served from the NVMe cache. For inference workloads that reload the same model across restarts, the storage bottleneck disappears after the first run.
The Cost Argument
| Option | Capacity | Effective speed (hot data) | Cost |
|---|---|---|---|
| 4TB NVMe | 4TB | NVMe | ~£400 |
| 1TB NVMe + 4TB SATA used | 4TB | NVMe (cached) | ~£130-140 |
The bcache setup delivers the same experience for actively used data at a third of the price. Cold data is slower, but cold data is cold - you're not waiting on it. The tradeoff only matters during the first load of a model that isn't in cache yet, and even then SATA speed is acceptable for a one-time cost.
If your workload rotates through models frequently enough that the 1TB cache can't keep up, size the NVMe accordingly. But for most setups - a handful of models in active use with occasional switches - 1TB of cache is more than enough.