VM and mirror investigation
Pracino iOS Simulator
Performance Investigation
The current 8-vCPU / 12-GiB VM allocation is already sensible. The remaining opportunities are in the idb video path and avoiding duplicate Simulator rendering, not in assigning more hardware or running QEMU headless.
01Decision
Keep the VM allocation. Improve the mirror path in a few controlled experiments.
Keep 8 vCPU and 12 GiB RAM. Live measurements showed CPU headroom, healthy guest memory pressure, no guest swapping, and essentially no I/O wait.
The visible ceiling is currently 15 fps. The mirror explicitly requests 15 fps, so it cannot look fully fluid regardless of spare CPU.
The fundamental ceiling is graphics acceleration. macOS sees a basic VMware framebuffer rather than the GPU acceleration Simulator normally gets on a real Mac.
02Allocation sweet spot
The current allocation is balanced for a 32-GiB, 6-core / 12-thread host.
During a representative run, the host remained roughly 56% idle. Individual QEMU vCPU threads were not saturated, QEMU had no swapped pages, guest memory pressure reported substantial headroom, and guest swap-in/out remained at zero.
| Configuration | Expected result | Verdict |
|---|---|---|
| 8 vCPU / 12 GiB | Good Xcode build capacity without squeezing Linux | ✓ |
| 6 vCPU / 10-12 GiB | May help only during heavy simultaneous host workloads; slower builds possible | Optional A/B |
| 8 vCPU / 16 GiB | Less RAM for Linux with no evidence the guest needs it | ✕ |
The approximately 980 MiB of host swap in use was not QEMU memory and there was no current I/O pressure. It is not evidence that the VM needs a different allocation.
03Experiments worth doing
Ordered by likely benefit relative to effort.
- 1Test current upstream idb H.264The installed companion is stable 1.1.8 from 2022. Yesterday's test established that this version's H.264 and MJPEG paths do not work here. The new experiment is an isolated current-HEAD companion/client test against Xcode 26.5, with 1.1.8 preserved as the fallback.
- 2Close Simulator.app, keep CoreSimulator bootedidb captures the booted simulator directly. If streaming and input continue after closing only Simulator.app, macOS avoids compositing a second visible copy of the simulator.
- 3Try raw video at 20 fpsThe viewer currently defaults to 15 fps. Twenty fps is the practical next step; 30 fps raw is much more expensive.
- 4Forward the idb port directly through QEMUUse SSH to manage the companion, but remove SSH encryption and copying from the high-volume raw video stream.
- 5Make QEMU priority apply to vCPU threadsThe current delayed renice affects the main QEMU thread but not its already-created vCPU threads. Starting QEMU at the desired priority may reduce stutters under host contention.
- 6Consider passt networkingQEMU documents passt as faster than its built-in user-mode networking, but this is a later optimization because it adds setup.
Raw BGRA traffic at the current simulator geometry is approximately 48 MB/s at 15 fps, 64 MB/s at 20 fps, and 96 MB/s at 30 fps. Making current H.264 work would therefore be the most valuable result.
04Things not worth chasing
These do not address the measured bottleneck.
- Headless QEMU:
-display nonehides the host window but leaves the guest graphics adapter and WindowServer work intact. Previous experience and QEMU's semantics agree: negligible practical benefit. - More CPU or RAM: neither resource was exhausted during measurement.
- GStreamer micro-optimization: the Linux GTK viewer consumed only a fraction of one CPU core.
- NoMachine: it adds complexity without improving the direct simulator workflow and should be removed from the skill's recommended path.
05ios-bridge assessment
Interesting architecture for remote multi-user access, but not a faster local mirror.
Recommendation: do not adopt it for this setup. It wraps the same idb primitives in FastAPI, Electron and WebRTC, adding layers without removing our underlying limitations.
Its input service shells out to idb ui tap, swipe, text, and button commands, so it does not provide a new continuous-touch mechanism. Its advertised low-latency stream runs idb video-stream --format h264 into a temporary file, repeatedly checks/reopens that file and decodes frames. That depends on the same H.264 path that failed in the current VM. Its alternative path repeatedly captures screenshots, base64-decodes and resizes them before WebRTC transport.
It could be useful for browser access, multi-user sessions or device-farm management. For a single Linux workstation seeking minimum latency, the existing direct idb-to-GStreamer path is leaner.
References: ios-bridge, device input service, low-latency service, fast WebRTC service.
06References
Primary documentation behind the conclusions.