En la cultura del desarrollo, pocas cosas desesperan tanto como sentir que el portátil “va sobrado” y, aun así, cada compilación parece perder segundos en un lugar invisible. Eso es exactamente lo que le ocurrió al desarrollador Nick Nethercote al analizar en macOS los tiempos de cargo build --timings: lo que debería ser una parte menor del proceso —los build scripts— se estaba convirtiendo en un cuello de botella extraño, irregular y, sobre todo, creciente.
El síntoma era llamativo. En un proyecto con decenas (o cientos) de dependencias, los build scripts aparecían en el gráfico de tiempos como barras anormalmente largas: algunos tardaban entre 0,48 y 3,88 segundos en ejecutarse. Y lo más raro: cuantos más se lanzaban, más se ralentizaba el conjunto. En Linux, ese mismo tipo de scripts —a veces tan simples como consultar la versión del compilador— se ejecutaban en un suspiro. En macOS, parecían caminar con botas de plomo.
Los build scripts que nadie mira… hasta que duelen
Para quien no conviva a diario con la mecánica interna de Cargo, los build scripts (normalmente build.rs) son pequeños programas que se ejecutan durante la compilación para tareas “extra”: detectar bibliotecas del sistema, compilar un trozo de C, generar código, ajustar opciones según el entorno, etc. Algunos son, por naturaleza, lentos. Pero muchos son triviales: una consulta, un cálculo, una comprobación.
Y ahí estaba la anomalía: scripts triviales que, en macOS, se comportaban como si estuvieran haciendo un trabajo pesado. Nethercote incluso comprobó que, ejecutados fuera de Cargo, esos mismos binarios eran más rápidos. El problema no era el código del script. Parecía otra cosa.
La explicación: no era Cargo, era el antivirus integrado de macOS
La pista llegó desde la comunidad: la causa podía estar en verificaciones de seguridad del sistema. Y el culpable tenía nombre: XProtect, la tecnología antivirus integrada en macOS.
Apple describe XProtect como una capa de defensa basada en firmas, con capacidad de detectar y bloquear malware conocido. Entre otras situaciones, el sistema puede analizar software cuando se ejecuta por primera vez, cuando ha sido modificado o cuando se actualizan las firmas. Eso, aplicado al día a día del desarrollo, tiene un efecto colateral evidente: si el sistema decide “mirar” cada binario nuevo antes de permitir su ejecución, el coste se paga justo donde más molesta.
Rust —y especialmente Cargo— encaja mal con ese patrón por un motivo simple: la herramienta genera y ejecuta muchos binarios pequeños (build scripts, herramientas auxiliares, pruebas, etc.) que, en muchos casos, se lanzan una sola vez. Es decir: el peor escenario posible para un escaneo de “primera ejecución”.
El detalle que lo empeora: un cuello de botella en cadena
La historia tiene un giro aún más doloroso: según la investigación compartida alrededor del tema, el servicio asociado a estas verificaciones puede actuar de forma esencialmente serializada. Traducido al lenguaje del desarrollador: si el sistema decide inspeccionar una tanda de ejecutables y lo hace con poca paralelización, los procesos se ponen en cola. Resultado: el último build script puede parecer lentísimo no porque su trabajo sea mayor, sino porque ha esperado turno.
Este matiz explica por qué el fenómeno se percibe como una degradación progresiva dentro de la misma compilación. En proyectos grandes, donde Cargo intenta aprovechar núcleos y lanzar tareas en paralelo, el sistema puede introducir una espera “invisible” que rompe el ritmo.
El “ajuste secreto”: convertir la Terminal en “herramienta de desarrollador”
Aquí llega lo que muchos han empezado a llamar el “truco” de macOS: marcar la aplicación de terminal (Terminal, iTerm2 u otra) como Developer Tool en los ajustes del sistema. En la práctica, esto reduce o evita esas comprobaciones para binarios lanzados desde esa terminal, lo que se traduce en menos latencia por ejecución.
Nethercote documenta una mejora muy clara en sus mediciones: tras aplicar el ajuste, los build scripts pasaron a tardar aproximadamente entre 0,06 y 0,14 segundos. En su ejemplo concreto, el tiempo total de compilación apenas bajó (de 25,9 a 25,0 segundos), pero el cambio importante era otro: la sensación de “atasco” desaparecía y el sistema volvía a comportarse de forma consistente.
Donde el impacto puede ser realmente grande no es tanto en cargo build, sino en el ciclo de desarrollo continuo: cargo run y, sobre todo, cargo test.
La gran sorpresa: pruebas mucho más rápidas (a veces, muchísimo)
El mundo Rust —y cualquier ecosistema con pruebas ejecutables— sufre especialmente cuando cada test genera un binario independiente. Es el caso de muchas pruebas de integración, y también de algunos doctests. Si cada ejecutable paga una “tasa” de verificación, el total se dispara.
En el propio ejemplo citado por Nethercote, el caso extremo lo pone el compilador de Rust y su suite tests/ui/, con miles de ejecutables pequeños. Un desarrollador reportó una reducción de tiempo de 9 min 42 s a 3 min 33 s tras aplicar el ajuste. Es el tipo de diferencia que cambia hábitos: lo que antes se ejecutaba “con café”, pasa a ejecutarse “entre commits”.
Además, aunque el foco sea Rust, el razonamiento es transferible: cualquier lenguaje compilado que genere muchos binarios temporales y los ejecute con frecuencia (C/C++, Go, Swift, etc.) podría notar mejoras, aunque el efecto exacto dependerá del flujo de trabajo.
El precio: rendimiento a cambio de una decisión de seguridad
Este punto es clave y no conviene maquillarlo: el ajuste implica renunciar a una capa de protección en un contexto concreto. No es un “hack” inocente para ganar rendimiento sin consecuencias. Es una decisión consciente sobre el equilibrio entre velocidad y seguridad.
Para equipos corporativos, entornos regulados o perfiles con alta exposición a binarios de procedencia desconocida, la recomendación no puede ser alegre. Para desarrolladores con un entorno controlado, que ejecutan binarios locales y conocen el origen de sus dependencias, la decisión puede tener sentido. Pero, en ambos casos, conviene entender qué se está sacrificando.
Hacia una solución menos “misteriosa”: que Cargo lo avise
Un aspecto interesante de esta historia es que deja de ser “folklore” para convertirse en conocimiento accionable. Ya existe una propuesta para que Cargo detecte el escenario y muestre una advertencia informativa: no para desactivar nada automáticamente, sino para explicar por qué ocurre y qué opciones tiene el usuario.
Porque lo más llamativo, quizá, no es que macOS tenga defensas agresivas. Es que, durante años, la explicación haya estado enterrada en hilos dispersos, comentarios y documentación secundaria. Y mientras tanto, miles de desarrolladores han asumido que “Rust compila lento en Mac” sin sospechar que, en parte, era el sistema operativo haciendo su trabajo… en el peor momento posible.
Preguntas frecuentes
¿Por qué macOS puede ralentizar cargo build o cargo test en Rust?
Porque macOS puede analizar ejecutables al primer lanzamiento mediante XProtect y tecnologías relacionadas. En proyectos Rust se generan muchos binarios pequeños (build scripts y tests) que se ejecutan una sola vez, lo que amplifica el coste.
¿Qué opción de macOS permite acelerar compilaciones y tests de Rust?
Marcar la aplicación de terminal (Terminal, iTerm2, etc.) como Developer Tool en los ajustes de privacidad/seguridad puede reducir esas verificaciones para binarios lanzados desde la terminal, acelerando el ciclo de compilación y ejecución.
¿Se nota más en cargo test que en cargo build?
A menudo sí. Las pruebas pueden generar y ejecutar una gran cantidad de binarios (especialmente tests de integración), por lo que el ahorro acumulado puede ser mucho mayor que en una compilación normal.
¿Es seguro aplicar este ajuste para acelerar Rust en macOS?
Implica un compromiso: se reduce una capa de verificación de seguridad en ese contexto. En entornos sensibles o con riesgo de ejecutar binarios no confiables, puede no ser recomendable. En un entorno de desarrollo controlado, puede ser una decisión razonable si se entiende el trade-off.
TIL that macOS has a security feature called XProtect, which scans any new binaries you execute
— Daniel Lockyer (@DanielLockyer) December 24, 2025
But it also means it slows down edit-compile-run workflows with excessive checking
And the daemon is single threaded, so concurrent binary executions are blocked
good lord pic.twitter.com/5BmXjgunSy








