Some data deserves to live only in memory: temporary build artifacts, high-speed caches written and read repeatedly during load testing, scratch files you don’t want wearing out your SSD. For this kind of need there’s no third-party tool to install — the Linux kernel’s built-in brd module conjures a “disk” out of thin air with a single modprobe, with read/write speed equal to memory bandwidth.

Honest boundary: brd is a kernel module, and a container environment cannot load host kernel modules, so this post’s flow was not actually run; the commands come from the original article and were cross-checked against the kernel documentation (Documentation/admin-guide/blockdev/ramdisk.rst) and the systemd documentation. They apply generally to CentOS 7/8/9 and Rocky Linux.

The Core Mechanism in One Sentence

brd (block device in RAM) wraps a region of memory into a standard block device inside the kernel: what you get is a genuine /dev/ramN device node, which you can partition and format with any filesystem via mkfs — that’s its biggest difference from tmpfs.

Create the RAM Disk

Load the brd module, with the parameters attached directly:

1
modprobe brd rd_nr=1 rd_size=16777216 max_part=0

Three parameters: rd_nr is how many disks — 1 here; rd_size is the size of each disk in KB — 16777216 KB is exactly 16 GB; max_part=0 disables partition support so the whole disk is used as one piece.

Once the module is loaded, a disk named ram0 appears under /dev. Confirm it:

1
lsblk /dev/ram0

Verification point: lsblk must show ram0 with a SIZE column matching rd_size (16G) before the module counts as loaded. If you want to benchmark the speed, dd if=/dev/zero of=/data/test bs=1M count=1024 oflag=direct writes 1 GB and reads out the throughput; the result is decided by the machine’s memory bandwidth.

Format and Mount

A RAM disk follows the same procedure as an ordinary disk. First format it as ext4:

1
mkfs.ext4 /dev/ram0

Then mount it to a directory (the mount-point directory must already exist):

1
2
mkdir -p /data
mount /dev/ram0 /data

From then on, everything written to /data lands in memory and is lost at power-off — that’s exactly the point of using it, and exactly its price.

Tear It Down When Done

When you’re finished, wind it down in order: unmount the filesystem, then remove the kernel module:

1
2
umount /data
modprobe -r brd

modprobe -r unloads brd from the kernel, and the data on the disk goes with it. Skip the umount and try -r directly, and the module can’t unload because it’s still in use — this order cannot be reversed.

Automatic Creation and Mounting at Boot

modprobe’s effect is gone after a reboot. Boot-time automation has to solve two separate problems: who loads the module, and who formats and mounts it — both are indispensable.

Hand module loading to systemd’s modules-load.d mechanism, with the parameters fixed into the modprobe configuration:

1
2
echo "brd" > /etc/modules-load.d/memdisk.conf
echo "options brd rd_nr=1 rd_size=16777216 max_part=0" >> /etc/modprobe.d/memdisk.conf

Note: writing only the options line in /etc/modprobe.d does not trigger a load — it only defines “which parameters to load with”. It’s modules-load.d (the systemd-modules-load service, read automatically at boot) that actually brings brd up; the two pieces only work as a pair. Source: systemd-modules-load.service(8) and modprobe.d(5).

Hand formatting and mounting to rc.local — a RAM disk comes up empty every boot, so both mkfs and mount must happen again:

1
2
3
echo "mkfs.ext4 /dev/ram0" >> /etc/rc.d/rc.local
echo "mount /dev/ram0 /data" >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local

To verify the auto-start actually works: reboot once, and only when lsblk /dev/ram0 shows the device and df -h /data shows the mount in place is the loop closed. A more modern alternative is writing the last two lines as a oneshot systemd unit — clearer semantics than rc.local, and easier to manage uniformly across many machines.

brd or tmpfs: Choose Wrong and All Your Effort Is Wasted

Both are in-memory storage, but their semantics differ — align on that first:

brd tmpfs
Form Block device /dev/ramN Filesystem, mounted as a directory
Filesystem Any (ext4/xfs… your choice) Fixed to tmpfs itself
Partitions/partition table Supported (max_part>0) Not applicable
Typical uses Apps that insist on a /dev device, a specific FS Build caches, session files

tmpfs is instantly usable with one mount -t tmpfs -o size=4G tmpfs /mnt; the access path is just a directory, and for most scenarios it’s the least-effort choice. brd’s value is block-device semantics: some databases and test tools insist on a /dev/ device, or need the disk formatted as a particular filesystem (xfs, say) — tmpfs can’t give them that, and brd fills the gap. Conversely, if all you want is to speed up your builds, tmpfs alone is enough, and detouring through brd is superfluous.

Common Errors

  • modprobe: FATAL: Module brd not found: the current kernel doesn’t ship the brd module (some cloud images, trimmed-down kernels). First check ls /lib/modules/$(uname -r)/kernel/drivers/block/ for a brd.ko; if it’s not there, you need a different kernel or the tmpfs approach.
  • modprobe: ERROR: could not insert 'brd': Operation not permitted: the classic error from running inside a container — containers share the host kernel and have no module-loading privileges, so kernel-module solutions like brd can only be done on real machines or VMs.
  • /data isn’t mounted after reboot: check three steps — “does the modules-load.d file exist, does rc.local have the execute bit, is the rc-local service active” — and the vast majority turn out to be the third: newer distributions don’t enable rc.local by default, and systemctl status rc-local tells you at a glance.

Notes and Cautions

  • A RAM disk has zero persistence: put only regenerable temporary data there, never important files.
  • The disk consumes real physical memory: whatever rd_size you give it, filling it takes exactly that much — size it to actual need, don’t arbitrarily open it large.
  • Create the mount-point directory first; mount will not mkdir for you.
  • The module cannot unload before umount; conversely, a reboot wipes the data and the device together, so any script depending on the disk must assume “it’s an empty disk every time.”

Summary

Back to the opening scenarios: for “use-once-and-discard” data like build artifacts and load-test caches, a single modprobe with brd hands you a block device running at memory bandwidth. Remember four things — data doesn’t persist, capacity is real memory, boot-time auto-start requires modules-load.d and rc.local working together, and the division of labor with tmpfs is “block-device semantics vs. ready-to-use directory” — and it’s a temporary high-speed disk on demand.


This article was rebuilt from the author’s CSDN blog posts published between 2020 and 2024, originally published on CSDN.