Optimal File System Block Size Selection: Performance Tradeoffs in Unix/Linux Filesystems


2 views

Block size determines the smallest allocatable unit of storage in a filesystem. When creating a filesystem with mkfs, the -b option specifies block size in bytes. Common values range from 1K to 64K:


# Creating ext4 with different block sizes
mkfs.ext4 -b 1024 /dev/sda1  # 1K blocks
mkfs.ext4 -b 4096 /dev/sda1  # 4K blocks (default)
mkfs.ext4 -b 65536 /dev/sda1 # 64K blocks

Large block sizes (8K-64K) excel for:

  • Database systems (MySQL, PostgreSQL)
  • Media editing applications
  • Virtual machine disk images
  • Scientific computing datasets

Small block sizes (1K-4K) work better for:

  • Source code repositories
  • Configuration files
  • Log files with frequent small writes
  • Mail servers with many small messages

Different filesystems have different optimal block size behaviors:


# XFS typically performs best with larger blocks
mkfs.xfs -b size=64K /dev/sdb1

# ZFS handles block sizing automatically with recordsize
zpool create -o recordsize=128K tank /dev/sdc1

# Btrfs defaults to 16K leaf size but can be tuned
mkfs.btrfs -L myvol --nodesize 32K /dev/sdd1

Use fio to test performance with various block sizes:


# Test sequential reads with 64K blocks
fio --name=seqread --rw=read --bs=64k --size=1G --runtime=60 --filename=/mnt/testfile

# Test random writes with 4K blocks
fio --name=randwrite --rw=randwrite --bs=4k --size=1G --runtime=60 --filename=/mnt/testfile

Modern filesystems use techniques to mitigate block size tradeoffs:

  • Extent-based allocation (ext4, XFS) groups blocks contiguously
  • Tail packing (btrfs) stores small files efficiently in large blocks
  • Compression (ZFS, btrfs) changes effective block utilization

In Unix/Linux file systems, the block size represents the smallest unit of data that can be allocated for storage. When creating a filesystem with mkfs commands, the block size significantly impacts performance characteristics:

# Common mkfs commands with block size specification
mkfs.ext4 -b 4096 /dev/sdX1  # 4KB blocks (default for ext4)
mkfs.xfs -b size=4096 /dev/sdX1
mkfs.ufs -b 8192 /dev/sdX1  # 8KB blocks for UFS

The block size selection involves balancing several factors:

  • Large blocks (8KB-64KB): Better for sequential I/O with large files (media storage, databases)
  • Small blocks (512B-4KB): Efficient for systems with many small files (source code repositories, config files)

Different filesystems have different optimal configurations:

Filesystem Recommended Block Size Typical Use Case
ext4 4KB (default) General purpose systems
XFS 4KB-64KB Large files, parallel I/O
ZFS 4KB-128KB Variable based on recordsize
Btrfs 4KB (fixed) SSD optimization

Here's how to test performance with different block sizes:

# Create test filesystems
dd if=/dev/zero of=testfs.img bs=1G count=10
mkfs.ext4 -b 1024 testfs.img
mkfs.ext4 -b 4096 testfs.img
mkfs.ext4 -b 65536 testfs.img

# Benchmark with fio
fio --name=randread --ioengine=libaio --rw=randread --bs=4k --numjobs=16 \
    --size=1G --runtime=60 --time_based --direct=1 --group_reporting \
    --filename=/mnt/testfs/testfile

Modern systems introduce additional factors:

  • SSD Alignment: 4KB blocks align with SSD page sizes
  • Compression: Larger blocks may compress better (ZFS/Btrfs)
  • RAID: Stripe size should be multiple of block size

For specific workloads:

# Database server (PostgreSQL/MySQL):
mkfs.xfs -b size=8k -d su=64k,sw=4 /dev/dbvolume

# Web server (many small files):
mkfs.ext4 -b 4096 -O dir_index /dev/webvolume

# Media storage (large video files):
mkfs.xfs -b size=64k /dev/mediavolume