The frame that actually matters: disposable changes the math
A lot of published VM performance advice optimizes for crash consistency on a server you patch in place for years. A disposable workspace that gets deleted the moment you close it has a different risk profile entirely — data loss on an ungraceful shutdown is a non-issue when the whole disk image is thrown away on the next run anyway. That changes which tradeoffs are actually worth making inside the guest, and it's the lens every recommendation below is filtered through: what's genuinely free, what's a real tradeoff worth taking specifically because the VM is disposable, and what's advice written for a context this isn't.
I/O scheduler: set it to none
Linux's I/O scheduler exists to reorder and merge requests to minimize physical disk-head movement. A virtio-blk root disk isn't a physical disk with a head to move — it's backed by a sparse image file the host already manages, and the host has its own view of what's actually efficient. Red Hat's own virtualization tuning documentation is direct about this: guests running on virtualized storage generally benefit from the none scheduler (the modern name for what used to be called noop) precisely because a second layer of reordering inside the guest is redundant with — and sometimes actively working against — whatever the host is already doing. The numbers back it up: kernel benchmarking discussions around virtio_blk found mq-deadline pulling roughly 270k 4K random-read IOPS against none's 450k on the same virtio-backed device. The one real exception is a guest with genuine passthrough or SR-IOV access to physical storage, where the guest actually does benefit from making its own scheduling decisions — not a case that applies here, since Apple's Virtualization.framework doesn't expose device passthrough to a Linux guest at all.
Check and set it with:
cat /sys/block/vda/queue/scheduler
echo none | sudo tee /sys/block/vda/queue/scheduler
TRIM: keeping the sparse disk image actually sparse
This one matters specifically because of how this app's workflow uses disk images. A sparse backing file only shrinks when the guest tells the host which blocks are now free — Apple's virtio-blk implementation supports the standard VIRTIO_BLK_F_DISCARD feature for exactly this, but it only does anything if the guest filesystem actually issues TRIM/discard requests. Skip this and a workspace's disk image only ever grows to its high-water mark for the life of the workspace, even as you delete files inside it — a real, documented failure mode in sparse-image implementations generally, not specific to any one virtualization stack.
The standard modern approach is a periodic fstrim pass rather than the discard mount option — most distros now ship fstrim.timer enabled by default for exactly this reason, batching the discard work instead of paying a small overhead on every single delete:
sudo systemctl enable --now fstrim.timer
sudo fstrim -v /
Worth doing by hand right before you seal a workspace as a base image, too — a smaller sealed image means less to copy on every subsequent clone.
Memory: zram beats a swapfile on the virtual disk
For a memory-constrained profile — a smaller AI Sandbox configuration, say — the standard advice to keep swappiness low to avoid disk-based swap thrashing doesn't transfer cleanly here, because zram-backed swap isn't disk I/O at all. It's compression against RAM you already have, with no trip through the virtio-blk path and no additional writes to the disk image you're trying to keep small via TRIM above. Because it's genuinely fast — no seek time, no queueing behind other disk I/O — the usual low-swappiness guidance inverts: zram setups are commonly tuned with vm.swappiness well above the traditional default, sometimes 100 or higher, specifically to make the kernel willing to use it instead of dropping filesystem cache first.
sudo apt install zram-tools # or: dnf install zram-generator
echo 'vm.swappiness=150' | sudo tee /etc/sysctl.d/99-zram.conf
Filesystem journaling: a real tradeoff, not a free win
Be precise about this one rather than quietly recommending it, because it's the one setting here with a genuine, honest downside. ext4's default data=ordered journaling mode protects against a specific failure: a crash leaving a file with garbage or stale data because metadata and content got written out of order. Switching to data=writeback drops that specific guarantee — a crash immediately after a write can leave incorrect data in the file that was being written — in exchange for meaningfully better throughput, since it journals metadata only rather than data too. For a long-lived server, that's a bad trade. For a disposable workspace that's deleted on close regardless of how it exits, the failure mode data=writeback exposes you to overlaps almost entirely with a failure mode you've already accepted by using a disposable VM in the first place — so it's a legitimate choice here specifically, not a generally-safe default to carry elsewhere.
noatime is the genuinely free win in the same neighborhood: skipping the access-time metadata write on every file read, with essentially no application that actually depends on it. Both go in /etc/fstab:
UUID=xxxx / ext4 defaults,noatime,data=writeback 0 1
Shared folders: VirtioFS caching mode
Shared folders and the Rosetta share both run over VirtioFS, and its caching mode is a direct coherency-versus-speed dial: none forbids client-side caching for maximum coherency at the cost of speed, auto behaves similarly to NFS with roughly a one-second metadata cache lifetime, and always sets a long cache lifetime for real speed on workloads that stat a lot of small files — an npm install, a large git checkout — at the cost of coherency. That cost is concrete, not theoretical: there's a documented case of a host-side edit to a file in a read-only VirtioFS share not becoming visible to the guest for minutes under a long-cache configuration. If you're actively editing files on the host and expecting the guest to see changes immediately, that's worth knowing before it looks like a mysterious sync bug rather than the caching mode doing exactly what it was configured to do.
What's already handled for you
Several of the concerns above are already priced into how this app's workflow is meant to be used rather than something you have to reason through from scratch: workspaces are disposable by default, so the crash-consistency risk data=writeback trades away is one you're already accepting; base images clone via copy-on-write, so a smaller sealed image (helped by TRIM above) directly speeds up every future clone. The kernel-level settings themselves — scheduler, the fstrim timer, zram, fstab mount options, VirtioFS caching where it's exposed — are guest-OS-level knobs, set inside whichever distro you're running, whether that's Ubuntu, Debian, or Fedora. Worth setting once in a base image rather than repeating per workspace, given how cheaply that base image then clones.
Related reading: why VMs on Apple Silicon perform the way they do at the architecture level, and the disposable VM workflow this tuning is meant to serve. Or download Velo Workspaces and try it yourself.