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.