Optimize Linux RAID configuration for maximum disk performance with mdadm and advanced tuning

Advanced 45 min Apr 14, 2026 2,292 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Learn how to configure and optimize Linux RAID arrays with mdadm for maximum disk performance. This comprehensive guide covers RAID level selection, advanced mdadm parameters, kernel I/O scheduler optimization, and file system tuning for high-throughput workloads.

Prerequisites

  • Multiple disks (minimum 4 for RAID 10)
  • Root access
  • Basic understanding of storage concepts

What this solves

Linux RAID configuration with mdadm provides redundancy and performance benefits, but default settings often leave significant performance gains on the table. This tutorial shows you how to optimize RAID arrays for maximum disk throughput by selecting the right RAID level, configuring advanced mdadm parameters, tuning kernel I/O schedulers, and optimizing file system mount options for high-performance workloads.

Understanding RAID levels and performance characteristics

Different RAID levels provide varying levels of performance, redundancy, and storage efficiency. Understanding these trade-offs is crucial for optimal configuration.

RAID LevelRead PerformanceWrite PerformanceRedundancyStorage Efficiency
RAID 0ExcellentExcellentNone100%
RAID 1GoodModerate1 disk failure50%
RAID 5GoodPoor1 disk failure75% (4 disks)
RAID 6GoodPoor2 disk failures67% (4 disks)
RAID 10ExcellentGoodMultiple disk failures50%
Note: RAID 10 provides the best balance of performance and redundancy for most high-performance applications. RAID 5 and 6 should be avoided for write-heavy workloads due to the parity calculation overhead.

Step-by-step RAID configuration and optimization

Install mdadm and disk utilities

Install the necessary tools for RAID management and disk optimization.

sudo apt update
sudo apt install -y mdadm gdisk parted smartmontools hdparm
sudo dnf install -y mdadm gdisk parted smartmontools hdparm

Identify and prepare disks

List available disks and verify they are suitable for RAID configuration.

sudo fdisk -l
lsblk
sudo smartctl -a /dev/sdb
sudo smartctl -a /dev/sdc
sudo smartctl -a /dev/sdd
sudo smartctl -a /dev/sde

Clear any existing partition tables and create GPT partition tables for optimal alignment.

sudo sgdisk --zap-all /dev/sdb
sudo sgdisk --zap-all /dev/sdc
sudo sgdisk --zap-all /dev/sdd
sudo sgdisk --zap-all /dev/sde

Create optimized RAID 10 array

Create a RAID 10 array with optimized parameters for maximum performance. The chunk size and layout significantly impact performance.

sudo mdadm --create /dev/md0 \
  --level=10 \
  --raid-devices=4 \
  --layout=f2 \
  --chunk=512 \
  --bitmap=internal \
  --assume-clean \
  /dev/sdb /dev/sdc /dev/sdd /dev/sde

Save the RAID configuration to ensure it persists across reboots.

sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
sudo update-initramfs -u
Note: The chunk size of 512KB is optimal for most workloads. Larger chunks (1024KB) work better for sequential I/O, while smaller chunks (256KB) benefit random I/O patterns.

Optimize RAID array parameters

Configure advanced RAID parameters for maximum performance.

# Set stripe cache size for better write performance
echo 8192 | sudo tee /sys/block/md0/md/stripe_cache_size

# Optimize read-ahead settings
sudo blockdev --setra 65536 /dev/md0

# Set appropriate queue depth
echo mq-deadline | sudo tee /sys/block/md0/queue/scheduler
echo 128 | sudo tee /sys/block/md0/queue/nr_requests

Make these optimizations persistent by creating a systemd service.

[Unit]
Description=Optimize RAID array performance
After=local-fs.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c 'echo 8192 > /sys/block/md0/md/stripe_cache_size'
ExecStart=/bin/bash -c 'blockdev --setra 65536 /dev/md0'
ExecStart=/bin/bash -c 'echo mq-deadline > /sys/block/md0/queue/scheduler'
ExecStart=/bin/bash -c 'echo 128 > /sys/block/md0/queue/nr_requests'

[Install]
WantedBy=multi-user.target
sudo systemctl enable raid-optimize.service
sudo systemctl start raid-optimize.service

Configure optimal I/O scheduler for individual disks

Set the most appropriate I/O scheduler for the underlying disks based on their type.

# For SSDs, use none or mq-deadline
echo none | sudo tee /sys/block/sdb/queue/scheduler
echo none | sudo tee /sys/block/sdc/queue/scheduler
echo none | sudo tee /sys/block/sdd/queue/scheduler
echo none | sudo tee /sys/block/sde/queue/scheduler

# For HDDs, use mq-deadline or bfq
</code><h2><code>echo mq-deadline | sudo tee /sys/block/sdb/queue/scheduler</code></h2></pre>
<p>Make I/O scheduler settings persistent across reboots.</p>
<pre class="terminal"><code># Set I/O scheduler for SSDs
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="none"
# Set I/O scheduler for HDDs
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="mq-deadline"

Optimize kernel parameters for RAID performance

Configure kernel parameters to maximize RAID array performance and reduce latency.

# Increase dirty page cache limits for better write performance
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
vm.dirty_expire_centisecs = 1000
vm.dirty_writeback_centisecs = 100

# Optimize memory allocation for RAID
vm.vfs_cache_pressure = 50
vm.swappiness = 10

# Increase maximum read-ahead size
vm.max_readahead_kb = 512

# Optimize network and I/O performance
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216
sudo sysctl -p /etc/sysctl.d/99-raid-performance.conf

Create optimized file system

Create an ext4 file system with parameters optimized for RAID performance.

sudo mkfs.ext4 -F \
  -b 4096 \
  -E stride=128,stripe-width=256 \
  -O ^has_journal \
  -m 1 \
  -L raid_storage \
  /dev/md0

For XFS file system (better for large files and parallel I/O):

# sudo mkfs.xfs -f \
#   -d sunit=1024,swidth=2048 \
#   -l logdev=/dev/md0,size=128m \
#   -L raid_storage \
</code><h2><code>  /dev/md0</code></h2></pre>
</div>

<div class="info"><strong>Note:</strong> The stride and stripe-width values depend on your RAID configuration. For RAID 10 with 512KB chunks: stride = chunk_size / block_size = 524288 / 4096 = 128, stripe-width = stride × data_disks = 128 × 2 = 256.</div>

<div class="step">
### Configure optimized mount options
<p>Create the mount point and configure optimal mount options for maximum performance.</p>
<pre class="terminal"><code>sudo mkdir -p /mnt/raid_storage

Add the optimized mount configuration to fstab.

/dev/md0 /mnt/raid_storage ext4 defaults,noatime,nodiratime,data=writeback,barrier=0,delalloc,max_batch_time=0 0 2

For XFS file systems, use these mount options instead:

# /dev/md0 /mnt/raid_storage xfs defaults,noatime,nodiratime,logbufs=8,logbsize=32k,largeio,inode64 0 2

Mount the file system and verify the configuration.

sudo mount /mnt/raid_storage
sudo chown $USER:$USER /mnt/raid_storage
Warning: The barrier=0 and data=writeback options improve performance but reduce data safety. Only use them with UPS protection and battery-backed RAID controllers.

Monitor and optimize RAID performance

Set up monitoring and performance tracking for your RAID array.

# Monitor RAID status
sudo mdadm --detail /dev/md0

# Check real-time I/O statistics
sudo iostat -x 1

# Monitor RAID rebuild progress (if needed)
watch -n 1 'cat /proc/mdstat'

Create a monitoring script for ongoing RAID health checks.

#!/bin/bash

# Check RAID array health
RAID_STATUS=$(sudo mdadm --detail /dev/md0 | grep "State :" | awk '{print $3}')

if [ "$RAID_STATUS" != "clean" ]; then
    echo "RAID array /dev/md0 is not clean: $RAID_STATUS"
    # Send alert (configure mail or notification service)
    logger "RAID Alert: Array /dev/md0 status is $RAID_STATUS"
else
    echo "RAID array /dev/md0 is healthy"
fi

# Check disk temperatures and SMART status
for disk in sdb sdc sdd sde; do
    TEMP=$(sudo smartctl -A /dev/$disk | grep Temperature_Celsius | awk '{print $10}')
    if [ "$TEMP" -gt 50 ]; then
        echo "Warning: /dev/$disk temperature is ${TEMP}°C"
    fi
done
sudo chmod +x /usr/local/bin/raid-monitor.sh
# Add to crontab for regular monitoring
echo "*/5 * * * * /usr/local/bin/raid-monitor.sh" | sudo crontab -

Advanced performance tuning techniques

Enable write-back caching for maximum write performance

Configure write-back caching on the individual disks for improved write performance.

# Enable write caching (only with UPS/battery backup)
sudo hdparm -W1 /dev/sdb
sudo hdparm -W1 /dev/sdc
sudo hdparm -W1 /dev/sdd
sudo hdparm -W1 /dev/sde

# Verify write cache status
sudo hdparm -W /dev/sdb

Optimize for specific workload patterns

Configure RAID parameters based on your specific use case.

# For database workloads (small random I/O)
echo 256 | sudo tee /sys/block/md0/md/stripe_cache_size
sudo blockdev --setra 2048 /dev/md0

# For large file storage (sequential I/O)
echo 16384 | sudo tee /sys/block/md0/md/stripe_cache_size
sudo blockdev --setra 131072 /dev/md0

# For mixed workloads (balanced)
echo 8192 | sudo tee /sys/block/md0/md/stripe_cache_size
sudo blockdev --setra 65536 /dev/md0

Set up performance benchmarking

Install and configure tools to measure RAID performance improvements.

sudo apt install -y fio bonnie++ iozone3
sudo dnf install -y fio bonnie++ iozone3

Run comprehensive performance tests to validate your optimizations.

# Test random read/write performance
sudo fio --name=raid-test \
  --directory=/mnt/raid_storage \
  --rw=randrw \
  --rwmixread=70 \
  --bs=4k \
  --size=1G \
  --numjobs=4 \
  --runtime=60 \
  --group_reporting

# Test sequential read/write performance
sudo fio --name=seq-test \
  --directory=/mnt/raid_storage \
  --rw=rw \
  --bs=1M \
  --size=2G \
  --numjobs=1 \
  --runtime=30 \
  --group_reporting

Verify your setup

# Check RAID array status
sudo mdadm --detail /dev/md0

# Verify mount and file system
df -h /mnt/raid_storage
mount | grep md0

# Check current I/O scheduler and parameters
cat /sys/block/md0/queue/scheduler
cat /sys/block/md0/md/stripe_cache_size

# Verify individual disk settings
for disk in sdb sdc sdd sde; do
    echo "=== /dev/$disk ==="
    cat /sys/block/$disk/queue/scheduler
    sudo hdparm -W /dev/$disk
done

# Test basic I/O performance
time dd if=/dev/zero of=/mnt/raid_storage/test_file bs=1M count=1024 oflag=direct
time dd if=/mnt/raid_storage/test_file of=/dev/null bs=1M iflag=direct
rm /mnt/raid_storage/test_file

Common issues

SymptomCauseFix
Poor write performanceWrite cache disabled or small stripe cacheEnable write cache with hdparm -W1, increase stripe cache size
High CPU usage during I/OInappropriate I/O schedulerUse 'none' scheduler for SSDs, 'mq-deadline' for HDDs
Array won't start on bootMissing mdadm.conf entriesRun mdadm --detail --scan >> /etc/mdadm/mdadm.conf
Inconsistent performanceMisaligned partitions or wrong stride valuesRecreate filesystem with correct stride/stripe-width values
Disk overheatingInsufficient cooling or too aggressive cachingImprove case ventilation, reduce stripe cache size

Next steps

Automated install script

Run this to automate the entire setup

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. Fully managed, with one fixed contact who knows your setup.

You get one fixed contact who knows your setup

Rotterdam 01:25 · reachable in a message, no ticket form