macOS XProtect: The Hidden Performance Tax on Rust Builds and How to Fix It
Share this article
For Rust developers on macOS, a hidden system setting could be sabotaging build performance. When Nicholas Nethercote noticed Rust build scripts executing suspiciously slowly—sometimes taking nearly 4 seconds for trivial tasks—he uncovered macOS’s built-in antivirus, XProtect, as the culprit. This discovery reveals why Mac-based compilation feels sluggish and how to reclaim lost speed.
The Build Script Bottleneck
Build scripts (build.rs) handle pre-compilation tasks like feature detection. Nethercote observed these scripts running 4-50x slower on macOS than Linux, despite minimal logic. Direct execution outside Cargo was fast, pointing to environmental overhead:
"Each orange bar [in the timings chart] measures build script execution. Why were they taking between 0.48 and 3.88 seconds on Mac?"
Build script delays (orange) dominate Cargo’s timings output (Source: Nicholas Nethercote)
XProtect: Security at a Cost
macOS scans every new executable via XProtect—Gatekeeper’s malware-detection subsystem. For Rust workflows, this is catastrophic:
- Each build script binary is scanned on first run
- Test binaries (including per-doctest executables) trigger scans
- Parallel builds exacerbate delays as scans queue single-threaded
Nethercote confirmed Weihang Lo’s hypothesis:
"XProtect checks for known malicious content whenever an app is first launched or changed. Build scripts are the worst possible case."
The Fix: Opt-Out for Terminals
Disabling scans for terminal apps eliminates the overhead:
1. Open System Settings > Privacy & Security > Developer Tools
2. Add Terminal/iTerm as an allowed developer tool
3. Restart the terminal (reboot to revert)
Warning: This trades security for performance. Only apply if you trust your toolchain.
Performance Gains: Beyond Expectations
Results are transformative:
- Build scripts drop from 3.88s to 0.14s
- cargo run avoids per-executable scans
- cargo test sees massive wins: Rust’s tests/ui suite runs 6x faster (9m42s → 3m33s)
Post-optimization: Build script overhead nearly vanishes (Source: Nicholas Nethercote)
Wider Implications
While Rust suffers acutely, all compiled languages (C++, Go, Swift) face similar penalties. Community efforts are underway—like Mads Marquart’s Cargo PR to warn users—but awareness remains low. Until then, developers can manually disable XProtect and reclaim their compile cycles.