RAM Disk on macOS for Xcode DerivedData
I've been using this script, which I place at /usr/local/bin/dasramdisk.sh, for way more than ten years. In all that time I've never once benchmarked it to see if a RAM disk was any faster for random reads/writes than an SSD. That much of those SSD reads/writes probably just exist exclusively in RAM (cached by the kernel) for a while anyway means that the performance difference might be negligible. But performance was not my motivation.
Xcode spits out an unfathomable number of object files when it builds my projects. And that directly impacts the life of my SSD. And when the SSD in my Mac is soldered onto the motherboard, that's a big deal.
#!/bin/bash
RAMDISK_SIZE=32768
RAMDISK_NAME="DasRamDisk"
if [ ! -d "/Volumes/${RAMDISK_NAME}" ]; then
let RAMDISK_BLOCKSIZE=2048*${RAMDISK_SIZE}
echo "Creating ram disk with blocksize size: ${RAMDISK_BLOCKSIZE}"
BLOCK_DEVICE=$(hdiutil attach -nomount ram://${RAMDISK_BLOCKSIZE} | sed -e 's/[[:space:]]*$//')
# echo "Creating APFS file system on '${BLOCK_DEVICE}' named '${RAMDISK_NAME}'"
echo "Creating HFS+ file system on '${BLOCK_DEVICE}' named '${RAMDISK_NAME}'"
# diskutil eraseVolume HFS+ "$RAMDISK_NAME" $BLOCK_DEVICE
# diskutil eraseVolume APFS "$RAMDISK_NAME" $BLOCK_DEVICE
# diskutil apfs create "$BLOCK_DEVICE" "$RAMDISK_NAME"
diskutil eraseVolume HFS+ "$RAMDISK_NAME" "$BLOCK_DEVICE"
echo "Mounting at /Volumes/${RAMDISK_NAME}"
# mount -u -o owners "/Volumes/${RAMDISK_NAME}"
mount -u -o owners,noatime,nobrowse,nodev,nosuid "/Volumes/${RAMDISK_NAME}"
# --- Disable Spotlight indexing on this volume ---
echo "Disabling Spotlight indexing on /Volumes/${RAMDISK_NAME}"
sudo mdutil -i off -d "/Volumes/${RAMDISK_NAME}" >/dev/null 2>&1 || true
touch "/Volumes/${RAMDISK_NAME}/.metadata_never_index"
# -----------------------------------------------
SetFile -a V "/Volumes/${RAMDISK_NAME}"
mkdir "/Volumes/${RAMDISK_NAME}/Xcode"
chmod 777 "/Volumes/${RAMDISK_NAME}/Xcode"
fiEach time I boot my machine, which isn't particularly often, I run that shell script to create the ram disk and mount it. And that's it. Xcode is configured to dump its object files there.
As I was writing this blog post, it got me thinking that maybe I had overlooked some optimization opportunities. I have made changes to the script over time, particularly to keep it working with macOS upgrades. I knew to disable Spotlight indexing. I had Codex write a benchmarking script for me. It would create 1GB RAM disks in various configurations and benchmark a few things. The results:
+--------------------+-------+--------+----------+---------------+---------------+----------+----------+----------+
| Variation | FS | Status | Setup s | Seq Write | Seq Read | Create/s | Read/s | Delete/s |
+--------------------+-------+--------+----------+---------------+---------------+----------+----------+----------+
| apfs-default | APFS | OK | 1.644 | 6321.0 MiB/s | 10893.6 MiB/s | 12598 | 37383 | 13605 |
| apfs-noatime | APFS | OK | 2.587 | 6400.0 MiB/s | 10666.7 MiB/s | 12698 | 35088 | 12422 |
| hfsplus-default | HFS+ | OK | 3.130 | 6095.2 MiB/s | 10893.6 MiB/s | 15123 | 44944 | 22039 |
| hfsplus-noatime | HFS+ | OK | 3.007 | 6321.0 MiB/s | 10240.0 MiB/s | 14760 | 45198 | 20566 |
| jhfsplus-noatime | JHFS+ | OK | 3.027 | 5626.4 MiB/s | 10449.0 MiB/s | 13136 | 42328 | 21448 |
+--------------------+-------+--------+----------+---------------+---------------+----------+----------+----------+
Benchmark settings:
Ram disk size: 950 MiB
Sequential file: 512 MiB
Small-file workload: 8000 files x 8192 bytes
So, it seems that HFS+ is more performant than APFS. It could be my testing methodology, or the small size of the RAM disk – I don't know – but I was surprised that noatime didn't perform better.
Compared to apfs-default, hfsplus-default was:
- Small-file create: 15123/s vs 12598/s, about 20% faster
- Small-file read: 44944/s vs 37383/s, about 20% faster
- Small-file delete: 22039/s vs 13605/s, about 62% faster
- Sequential write/read: roughly tiedI used to try to get Safari to write all of its caches there, but Safari would frequently replace my alias / symlink with a folder, undoing my efforts, so I gave up on that.
Anyway, I give this to you, the people. Use it wisely. Also, change the RAMDISK_SIZE to something appropriate for your use and your available RAM. 32GB might not be a good place for you to start.