Creating a RAM Disk with the brd Kernel Module: Loading, Mounting, and Auto-Start at Boot
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 | mkdir -p /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 | umount /data |
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 | echo "brd" > /etc/modules-load.d/memdisk.conf |
Note: writing only the options line in
/etc/modprobe.ddoes 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 | echo "mkfs.ext4 /dev/ram0" >> /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 checkls /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-localtells 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.