Last updated: 2026-08-20

Linux storage tiering & caching

Category: Block CachingTechnologies: bcache, lvmcache, dm-cache, dm-writecache

Block-level caching places a fast device (SSD/NVMe) in front of a slow device (HDD) to accelerate I/O. The cache holds hot data; cold data stays on the backing device. Linux offers four main implementations: bcache, dm-cache, lvmcache (which wraps dm-cache), and dm-writecache. Run TRIM on the cache SSD so garbage collection keeps up with churn.

Cache modes

ModeWrite behaviorSafetyPerformance
writethroughWrites go to both cache and backing deviceSafe (no data loss if cache fails)Reads accelerated, writes not
writebackWrites go to cache only, flushed to backing laterRisky (data loss if cache fails before flush)Both reads and writes accelerated
writearoundWrites go directly to backing, bypassing cacheSafeReads of recently-written data not accelerated
none / passthroughI/O passes through to backing deviceSafeNo caching

bcache

bcache is a kernel block-layer cache that uses an SSD as a cache for one or more HDDs. It uses bucket-based allocation with a B+ tree index to track cached extents, and supports writeback, writethrough, writearound, and none modes.

Setup

# 1. Format the SSD as a cache device (bucket size should match SSD erase block)
make-bcache -C -b 512K /dev/nvme0n1p1

# 2. Format the HDD as a backing device
make-bcache -B /dev/sdb

# 3. Register devices with the kernel (if not auto-registered by udev)
echo /dev/nvme0n1p1 > /sys/fs/bcache/register
echo /dev/sdb > /sys/fs/bcache/register

# 4. Attach backing device to cache set (UUID from /sys/fs/bcache/)
ls /sys/fs/bcache/
echo <UUID> > /sys/block/bcache0/bcache/attach

# 5. Create filesystem on the bcache device
mkfs.ext4 /dev/bcache0
mount /dev/bcache0 /mnt/data

Cache mode

# View current mode (brackets indicate active)
cat /sys/block/bcache0/bcache/cache_mode

# Set mode at runtime
echo writeback > /sys/block/bcache0/bcache/cache_mode
echo writethrough > /sys/block/bcache0/bcache/cache_mode
echo writearound > /sys/block/bcache0/bcache/cache_mode
echo none > /sys/block/bcache0/bcache/cache_mode

Key tunables

Sysfs pathDefaultEffect
cache_modewritethroughCache policy
writeback_percent10Target dirty cache percentage before throttling writes
writeback_delay30Seconds to delay writeback after last write
sequential_cutoff4MSequential I/O threshold to bypass cache (0 = cache everything)
congested_read_threshold_us0Latency threshold to bypass cache on reads
dirty_data-Read-only: amount of unflushed dirty data

Sequential bypass

bcache detects sequential I/O and bypasses the cache to avoid evicting useful random data. Disable it if your workload benefits from caching large files:

# Disable sequential bypass (cache everything)
echo 0 > /sys/block/bcache0/bcache/sequential_cutoff

# Restore default (4M)
echo 4M > /sys/block/bcache0/bcache/sequential_cutoff

Stopping and detaching

# Detach cache (revert to passthrough)
echo 1 > /sys/block/bcache0/bcache/detach

# Stop a backing device
echo 1 > /sys/block/bcache0/bcache/stop

# Unregister a cache device
echo 1 > /sys/fs/bcache/<UUID>/unregister

Replacing a cache device

# 1. Switch to writethrough to ensure no dirty data
echo writethrough > /sys/block/bcache0/bcache/cache_mode

# 2. Wait for dirty data to flush
watch cat /sys/block/bcache0/bcache/dirty_data

# 3. Detach
echo 1 > /sys/block/bcache0/bcache/detach

# 4. Register new cache device
make-bcache -C -b 512K /dev/new_nvme
echo /dev/new_nvme > /sys/fs/bcache/register

# 5. Attach backing device to new cache set
echo <NEW_UUID> > /sys/block/bcache0/bcache/attach

dm-cache (device-mapper cache)

dm-cache is the kernel's device-mapper caching target. It is rarely used directly, lvmcache wraps it with a friendlier interface. dm-cache supports writethrough, writeback, and passthrough modes, and uses the smq (Stochastic Multi-Queue) policy by default.

lvmcache

lvmcache is the LVM interface to dm-cache. It creates a cache pool (metadata LV + cache data LV) on a fast device and attaches it to an existing LV on a slow device.

Setup with cache volume (simpler, recommended)

# Create cache volume on the fast device
lvcreate -L 20G -n fast_vol myvg /dev/nvme0n1p1

# Attach to existing LV (writeback mode)
lvconvert --type cache --cachevol myvg/fast_vol \
  --cachemode writeback myvg/main_lv

Setup with cache pool (traditional, more control)

# Create cache data and metadata LVs
lvcreate -L 20G -n cache_data myvg /dev/nvme0n1p1
lvcreate -L 1G -n cache_meta myvg /dev/nvme0n1p1

# Convert to cache pool
lvconvert --type cache-pool --poolmetadata myvg/cache_meta \
  myvg/cache_data

# Attach cache pool to origin LV
lvconvert --type cache --cachepool myvg/cache_pool \
  --cachemode writeback myvg/main_lv

One-step creation

lvcreate --type cache -L 100G -n cached_lv \
  --cachedevice /dev/nvme0n1p1 --cachesize 20G \
  --cachemode writeback myvg /dev/sdb1

Cache modes

# Set at creation
lvconvert --type cache --cachepool myvg/cache_pool \
  --cachemode writeback myvg/main_lv

# Change mode of existing cache
lvconvert --cachemode writethrough myvg/main_lv

Monitoring hit rate

# Show cache statistics
lvs -o lv_name,cache_mode,cache_policy,cache_read_hits,cache_read_misses, \
  cache_write_hits,cache_write_misses myvg/main_lv

# Cache utilization
lvs -o lv_name,data_percent myvg/main_lv

# Raw dm-cache status
dmsetup status myvg-main_lv

Pair hit-rate stats with disk benchmarks to measure the actual latency improvement.

Removing cache

# Flush dirty data and detach (safe for writeback)
lvconvert --splitcache myvg/main_lv

# Alternative: uncache
lvconvert --uncache myvg/main_lv

dm-writecache (LVM writecache)

dm-writecache is a simpler writeback-only cache designed specifically for SSD/NVMe write acceleration. Unlike dm-cache, it does not cache reads. It only buffers writes and flushes them to the backing device asynchronously.

# Create deactivated writecache LV on SSD
lvcreate -an -L 20G -n writecache myvg /dev/nvme0n1p1

# Unmount and deactivate origin LV
umount /data
lvchange -an myvg/main_lv

# Attach writecache
lvconvert --type writecache --cachevol myvg/writecache myvg/main_lv

# Reactivate and mount
lvchange -ay myvg/main_lv
mount /data

dm-writecache is best for write-heavy workloads on HDDs where read caching is less important. For mixed read/write workloads, dm-cache (lvmcache) is usually better.

Tool comparison

Featurebcachelvmcache (dm-cache)dm-writecache
Read cachingYesYesNo
Write cachingYes (writeback)Yes (writeback)Yes (writeback only)
WritethroughYesYesNo
WritearoundYesNoNo
Managementsysfs + make-bcacheLVM commandsLVM commands
Works with LVMCan put bcache under LVMNativeNative
Online attach/detachYesYesNo (requires offline)
Best forMax performance, non-LVMGeneral use, LVM environmentsWrite-intensive workloads

ZFS ARC/L2ARC/SLOG (comparison)

ZFS provides its own caching layers, which are filesystem-level rather than block-level:

Best practices

  1. Size cache at 5-10% of backing device for most workloads; 10-20% for write-intensive.
  2. Use NVMe/SSD for cache. HDD cache provides minimal benefit.
  3. Use enterprise SSDs for writeback mode: consumer SSDs can lose data on power failure.
  4. Start with writethrough until you trust the setup, then switch to writeback.
  5. Monitor hit ratios: if below 50%, the cache may not be helping.
  6. Have a recovery plan. Know how to recover from cache failure before you need to.
  7. Don't cache backups. Backup workloads are typically sequential and won't benefit.

Cache SSDs take extra write load, so monitor their SMART stats closely.

Sources & references

  1. A block layer cache (bcache) — official kernel documentation for bcache covering setup, cache modes (writethrough, writeback, writearound), and sysfs tunables
  2. Cache device-mapper target — kernel documentation for dm-cache explaining design, cache modes, and policy modules
  3. Writecache device-mapper target — documentation for dm-writecache explaining write-only caching on SSD/PMEM and constructor parameters
  4. lvmcache(7) — Linux manual page — man page documenting LVM's interface to dm-cache and dm-writecache, including lvconvert commands and cache modes

Frequently asked questions

What is the difference between bcache and lvmcache?

bcache is a standalone kernel block-layer cache managed through sysfs and `make-bcache`. lvmcache is the LVM interface to dm-cache, managed with standard LVM commands. bcache supports writearound mode and works outside LVM; lvmcache is native to LVM environments.

What is dm-writecache used for?

dm-writecache is a writeback-only cache that buffers writes and flushes them to the backing device asynchronously. It does not cache reads. It is best for write-heavy workloads on HDDs where read caching matters less. For mixed read/write workloads, dm-cache (lvmcache) is usually better.

What cache mode should I use?

Writethrough is safe because writes go to both cache and backing device, so no data is lost if the cache fails. Writeback accelerates both reads and writes but risks data loss if the cache fails before a flush. Start with writethrough until you trust the setup, then switch to writeback.

How do I replace a bcache cache device?

Switch to writethrough mode, wait for `dirty_data` to reach zero, detach the old cache, register the new device with `make-bcache` and `echo /dev/new_nvme > /sys/fs/bcache/register`, then attach the backing device to the new cache set UUID.

What size should my cache device be?

Size the cache at 5-10% of the backing device for most workloads, or 10-20% for write-intensive workloads. Use NVMe or SSD for cache; HDD cache provides minimal benefit. Use enterprise SSDs for writeback mode because consumer SSDs can lose data on power failure.

What is bcache sequential bypass?

bcache detects sequential I/O and bypasses the cache to avoid evicting useful random data. The `sequential_cutoff` tunable defaults to 4M. Set it to 0 to cache everything, which helps workloads that benefit from caching large files.

Can I attach or detach an lvmcache cache online?

Yes. Use `lvconvert --splitcache myvg/main_lv` to flush dirty data and detach the cache safely, or `lvconvert --uncache myvg/main_lv` as an alternative. dm-writecache is different: it requires the origin LV to be deactivated and unmounted before attaching.