Skip to content

MinIO single-server erasure coding: durability on one box with multiple disks

Run MinIO on a single server in erasure-coded mode across multiple disks, with the drive layout, parity ratio, and the limitations vs a true distributed MinIO cluster.

A single-server MinIO deployment with multiple disks is the sweet spot for small object storage workloads where you want durability against drive loss but don’t yet need cross-host distribution. MinIO’s “Single-Node Multi-Drive” (SNMD) mode stripes objects across local disks with a parity scheme that survives up to N/2 drive failures depending on your erasure set size. This article documents the install, the drive layout decisions that determine whether you actually get protection, and the operational reality of when single-server is enough and when you need a real distributed deployment.

How to verify

# Service status
sudo systemctl status minio
sudo journalctl -u minio --since "5 minutes ago" | tail -30

# Disk and erasure set layout
sudo mc admin info local
sudo mc admin server info local --json | jq '.servers[].drives'

# Health on a per-drive basis
sudo mc admin heal local --recursive --dry-run | head -20

What’s happening

MinIO in SNMD mode treats each disk as an independent member of an erasure set. When you write an object, MinIO splits it into data chunks plus parity chunks, distributes them across the disks, and stores a xl.meta metadata file on each disk that participated. If a disk fails, the data is still readable from the remaining disks; if you replace the failed drive, mc admin heal reconstructs the chunks on the new drive from parity. The erasure set size is fixed at deployment time and equals the number of drives you list in the command (must be 4, 6, 8, 12, or 16 typically).

Parity ratio matters. With 4 drives and the default EC:2 (2 data + 2 parity), you survive 2 drive failures and use 50% of raw capacity for data. With 8 drives at EC:4, same survival ratio but 50% capacity. With 16 drives at EC:4 (12 data + 4 parity), you survive 4 failures while using 75% of capacity — better economics but more disks to manage. The right ratio depends on workload: write-heavy systems push more I/O per parity update, so high-parity ratios cost more wall-clock time on writes.

The hard limit of SNMD is that the whole server is a single failure domain. A motherboard, PSU, or kernel panic takes the entire service down regardless of how many drives you have. MinIO documents SNMD as suitable for “non-critical” or “development” workloads precisely for that reason. We use it for client environments where the data has another upstream copy (object storage as a cache or staging tier for backups that also live elsewhere), and we move to multi-node distributed MinIO when the data is the only copy.

The procedure

  1. Prepare four dedicated drives (must be the same size, must be empty, must not be the boot disk):

    sudo mkfs.xfs -L MINIO1 /dev/sdb
    sudo mkfs.xfs -L MINIO2 /dev/sdc
    sudo mkfs.xfs -L MINIO3 /dev/sdd
    sudo mkfs.xfs -L MINIO4 /dev/sde
    sudo mkdir -p /mnt/minio/{1,2,3,4}
    echo 'LABEL=MINIO1 /mnt/minio/1 xfs defaults 0 2' | sudo tee -a /etc/fstab
    echo 'LABEL=MINIO2 /mnt/minio/2 xfs defaults 0 2' | sudo tee -a /etc/fstab
    echo 'LABEL=MINIO3 /mnt/minio/3 xfs defaults 0 2' | sudo tee -a /etc/fstab
    echo 'LABEL=MINIO4 /mnt/minio/4 xfs defaults 0 2' | sudo tee -a /etc/fstab
    sudo mount -a
  2. Install the MinIO server binary:

    wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio_20260101000000.0.0_amd64.deb
    sudo dpkg -i minio_*.deb
    sudo useradd -r minio-user -s /sbin/nologin
    sudo chown -R minio-user:minio-user /mnt/minio
  3. Configure /etc/default/minio:

    MINIO_VOLUMES="/mnt/minio/{1...4}"
    MINIO_OPTS="--console-address :9001 --address :9000"
    MINIO_ROOT_USER="minioadmin"
    MINIO_ROOT_PASSWORD="<generate-strong-password>"
    MINIO_SERVER_URL="https://s3.example.internal"
    MINIO_BROWSER_REDIRECT_URL="https://console.example.internal"

    The {1...4} ellipsis expands to four drives; that’s what triggers MinIO to use erasure coding instead of replicated mode.

  4. Start and enable:

    sudo systemctl enable --now minio
    sudo systemctl status minio
    sudo journalctl -u minio --since "1 minute ago"

    Look for log lines confirming “Erasure setup with N online drives”.

  5. Install the mc CLI client on the same host (or a workstation) for admin operations:

    wget https://dl.min.io/client/mc/release/linux-amd64/mc
    chmod +x mc
    sudo mv mc /usr/local/bin/
    mc alias set local http://localhost:9000 minioadmin <password>
    mc admin info local
  6. Create the first bucket and a non-root user:

    mc mb local/app-uploads
    mc admin user add local app01 <strong-secret>
    mc admin policy attach local readwrite --user app01
    mc anonymous set download local/app-uploads/public
  7. Verify EC layout works as expected by checking heal status:

    mc admin heal local --recursive --dry-run
    mc admin info local --json | jq '.servers[].drives[].state'

Common pitfalls

  • Using disks of unequal sizes — MinIO uses the smallest disk’s capacity for all of them and you lose capacity silently. Match drive sizes.
  • Single-disk SNMD doesn’t exist. With one drive, MinIO runs in “filesystem” mode without erasure coding, and that’s a different (worse) durability story.
  • Drives on the same controller share a failure domain — a bad HBA takes them all out. If you can spread drives across two HBAs, do.
  • The {1...4} syntax is sensitive: forgetting the ellipsis (/mnt/minio/1 /mnt/minio/2 ...) puts MinIO in distributed-server mode with one disk per host, which is not what you want on a single box.
  • Drive label vs UUID mounting: if drives change cable positions across reboots, label-based mounting keeps them straight. Don’t use raw device paths.

In the engagements we run, single-server MinIO with EC is fine for the “second copy” tier — a cache for cloud-hosted primary storage, a staging area for backup ingestion, or a non-prod environment where the cost of a multi-node deployment isn’t justified yet. We set up mc admin heal cron jobs that run weekly to catch silent bit rot, ship MinIO Prometheus metrics into the central observability stack, and document the failure domain clearly with the customer — single-server EC protects against drive loss, not server loss.