Skip to content

Sandbox Lifecycle: Under the Hood

Companion to Sandbox Lifecycle.

Sandbox kwargs to QEMU command

python
Sandbox(
    image="ubuntu",
    memory="2G",
    cpus=4,
    accel="auto",
)
bash
qemu-system-aarch64 \
  -nodefaults \
  -machine virt \
  -m 2G \
  -smp 4 \
  -L /path/to/share/qemu \
  -accel hvf \
  -cpu host \
  ...
Config fieldQEMU flagNotes
memory="2G"-m 2GPassed through as-is
cpus=4-smp 4Number of virtual CPU cores
accel="auto"-accel hvf (macOS)Auto-detected per platform (see below)
image="ubuntu"-kernel, -initrd, -driveResolved to image files on disk

-nodefaults strips QEMU's built-in devices (floppy, CD-ROM, serial ports, etc.) so the command builds the VM from scratch with only what's needed.

Machine type

The -machine flag is selected automatically based on architecture and platform:

ArchitecturePlatformMachineWhy
ARM64AnyvirtARM's standard virtual machine type
x86_64Anyq35Full-featured Intel chipset

Hardware acceleration

python
Sandbox(image="ubuntu")  # accel defaults to "auto"

Auto-detection selects the best available accelerator:

PlatformAcceleratorQEMU flagsCPU performance
macOSHVF-accel hvf -cpu hostNear-native
LinuxKVM-accel kvm -cpu hostNear-native
WindowsWHPX-accel whpx -cpu hostNear-native
Any (fallback)TCG-accel tcg -cpu max10-50x slower

With hardware acceleration (-cpu host), the guest runs on the real CPU. With TCG (-cpu max), QEMU translates every instruction in software.

On Windows inside a Hyper-V VM (nested virtualization), WHPX gets an extra flag: -accel whpx,kernel-irqchip=off.

Device naming by machine type

The machine type determines how virtio devices are attached:

MachineBlock deviceNetwork deviceBus type
virt (ARM64)virtio-blk-devicevirtio-net-deviceMMIO
q35 (x86_64)virtio-blk-pcivirtio-net-pciPCI

PCI devices have a small overhead from bus emulation. MMIO devices (used by virt) skip this entirely.

Full assembled command

Putting it all together, here's what Quicksand generates for a typical macOS ARM64 headless sandbox:

bash
qemu-system-aarch64 \
  -nodefaults \
  -machine virt \
  -m 512M \
  -smp 1 \
  -L /path/to/share/qemu \
  -object iothread,id=iothread0 \
  -drive file=overlay.qcow2,format=qcow2,if=none,id=drive0,cache=writethrough,discard=unmap,detect-zeroes=unmap \
  -device virtio-blk-device,drive=drive0,iothread=iothread0 \
  -serial stdio \
  -nographic -vga none \
  -cpu host \
  -accel hvf \
  -qmp tcp:127.0.0.1:4444,server,nowait \
  -kernel /path/to/ubuntu-24.04-arm64.kernel \
  -append "root=/dev/vda rw rootflags=rw console=ttyAMA0 rootfstype=ext4 quiet loglevel=0 raid=noautodetect quicksand_token=abc123 quicksand_port=8080" \
  -initrd /path/to/ubuntu-24.04-arm64.initrd \
  -netdev user,id=net0,restrict=on,hostfwd=tcp:127.0.0.1:8080-:8080,guestfwd=tcp:10.0.2.100:445-cmd:/path/to/smb_server \
  -device virtio-net-device,netdev=net0

Every flag here maps back to either a Sandbox kwarg or an automatic platform decision.