<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
    <title>Codigum</title>
    <subtitle>Guías, mediciones y criterio para construir software seguro y eficiente, en español y para Latinoamérica.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://codigum.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://codigum.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-11-05T00:00:00+00:00</updated>
    <id>https://codigum.com/atom.xml</id>
    <entry xml:lang="es">
        <title>¿Cuánto tarda un equipo en aprender Rust?</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/cuanto-tarda-un-equipo-en-aprender-rust/"/>
        <id>https://codigum.com/notas/cuanto-tarda-un-equipo-en-aprender-rust/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/cuanto-tarda-un-equipo-en-aprender-rust/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;Espera unos dos meses para contribuir con confianza y unos cuatro para recuperar tu ritmo, si el equipo aprende con método.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;La pregunta que frena a muchos líderes técnicos no es si Rust es bueno, sino cuánto tiempo perderá el equipo aprendiéndolo. La mala noticia es que la curva es real. La buena es que hay datos, y son mejores de lo que dice la fama.&lt;/p&gt;
&lt;h2 id=&quot;lo-que-dicen-los-datos&quot;&gt;Lo que dicen los datos&lt;/h2&gt;
&lt;p&gt;La mejor referencia pública es &lt;a rel=&quot;external&quot; href=&quot;https://opensource.googleblog.com/2023/06/rust-fact-vs-fiction-5-insights-from-googles-rust-journey-2022.html&quot;&gt;una encuesta de Google de 2022&lt;/a&gt;, respondida por más de 1000 desarrolladores que habían escrito Rust ese año:&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 188&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;De los desarrolladores de Google encuestados, más de dos tercios contribuyen con confianza en dos meses o menos; un tercio es igual de productivo en dos meses y más de la mitad en cuatro meses.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;18&quot;&gt;Contribuye con confianza, en 2 meses o menos&lt;/text&gt;&lt;rect class=&quot;dg__track&quot; x=&quot;0&quot; y=&quot;28&quot; width=&quot;340&quot; height=&quot;24&quot; rx=&quot;5&quot;/&gt;&lt;rect class=&quot;dg__frust&quot; x=&quot;0&quot; y=&quot;28&quot; width=&quot;227.8&quot; height=&quot;24&quot; rx=&quot;5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;352&quot; y=&quot;45&quot;&gt;más de 2/3&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;84&quot;&gt;Igual de productivo, en 2 meses o menos&lt;/text&gt;&lt;rect class=&quot;dg__track&quot; x=&quot;0&quot; y=&quot;94&quot; width=&quot;340&quot; height=&quot;24&quot; rx=&quot;5&quot;/&gt;&lt;rect class=&quot;dg__frust&quot; x=&quot;0&quot; y=&quot;94&quot; width=&quot;112.2&quot; height=&quot;24&quot; rx=&quot;5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;352&quot; y=&quot;111&quot;&gt;1/3&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;150&quot;&gt;Igual de productivo, en 4 meses o menos&lt;/text&gt;&lt;rect class=&quot;dg__track&quot; x=&quot;0&quot; y=&quot;160&quot; width=&quot;340&quot; height=&quot;24&quot; rx=&quot;5&quot;/&gt;&lt;rect class=&quot;dg__frust&quot; x=&quot;0&quot; y=&quot;160&quot; width=&quot;170&quot; height=&quot;24&quot; rx=&quot;5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;352&quot; y=&quot;177&quot;&gt;más de la mitad&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Encuesta a más de 1000 desarrolladores de Google que escribieron Rust en 2022. Son percepciones, no mediciones.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;Más de dos tercios se sintieron capaces de contribuir a un proyecto en Rust en &lt;strong&gt;dos meses o menos&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Un tercio alcanzó la misma productividad que en otros lenguajes en ese plazo, y más de la mitad en &lt;strong&gt;cuatro meses&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;El 85 % confía en que su código Rust es correcto, y el 77 % está satisfecho con su calidad.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El mayor problema reportado no fue el lenguaje, sino la velocidad de compilación: solo algo más del 40 % la consideró aceptable.&lt;/p&gt;
&lt;h2 id=&quot;como-leer-estas-cifras&quot;&gt;Cómo leer estas cifras&lt;/h2&gt;
&lt;p&gt;Antes de usarlas en un plan, tres matices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No todas las empresas son Google.&lt;/strong&gt; Hablamos de personas con mucha experiencia, buenas herramientas y compañeros que ya conocían el lenguaje.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Es lo que las personas dicen.&lt;/strong&gt; Son percepciones en una encuesta, no mediciones de productividad.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Depende de dónde vienes.&lt;/strong&gt; Quien viene de C++ ya entiende la memoria, y quien viene de Python o JavaScript debe aprender más conceptos, aunque suele hacerlo sin malos hábitos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Como referencia, la &lt;a rel=&quot;external&quot; href=&quot;https://blog.rust-lang.org/2026/03/02/2025-State-Of-Rust-Survey-results/&quot;&gt;encuesta State of Rust 2025&lt;/a&gt;, con 7156 respuestas completas, también sitúa los tiempos de compilación y el uso de recursos entre los retos que persisten.&lt;/p&gt;
&lt;h2 id=&quot;donde-se-atascan-los-equipos&quot;&gt;Dónde se atascan los equipos&lt;/h2&gt;
&lt;p&gt;La sintaxis se aprende rápido. Lo que toma tiempo es cambiar la forma de pensar:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;La propiedad y el préstamo.&lt;/strong&gt; Los primeros días, el compilador rechazará casi todo. Es normal. Empieza por la &lt;a href=&quot;https://codigum.com/aprende/ownership/&quot;&gt;guía de ownership&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Los tiempos de vida.&lt;/strong&gt; Asustan más de lo que deberían. La mayoría del código no los necesita de forma explícita, como vemos en la &lt;a href=&quot;https://codigum.com/aprende/lifetimes/&quot;&gt;guía de lifetimes&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Código asíncrono.&lt;/strong&gt; Suma varios conceptos a la vez. Conviene dejarlo para cuando lo anterior esté asentado.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Traer patrones de otro lenguaje.&lt;/strong&gt; Modelar con herencia o con muchos objetos que se apuntan entre sí trae problemas. Es mejor &lt;a href=&quot;https://codigum.com/aprende/enums-match/&quot;&gt;pensar en tipos&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Lo que más frena no es la dificultad, sino hacerlo a solas, sin nadie que revise el código.&lt;/p&gt;
&lt;h2 id=&quot;el-costo-real&quot;&gt;El costo real&lt;/h2&gt;
&lt;p&gt;El error habitual es contar solo el curso. El costo principal es el tiempo con menor productividad. Una forma simple de estimarlo:&lt;/p&gt;
&lt;aside class=&quot;callout callout--nota&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;La cuenta&lt;/p&gt;
&lt;p&gt;Costo de adopción = personas × meses de adaptación × costo mensual × pérdida de productividad + capacitación&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Un ejemplo con valores supuestos: cuatro personas, cuatro meses y una pérdida media del 30 % equivalen a 4,8 meses de una persona. A ese número se le suma la capacitación, y se le debe comparar el beneficio esperado: menos incidentes, menos infraestructura o mejor latencia.&lt;/p&gt;
&lt;p&gt;Si la cuenta no da, ese es un resultado valioso. Las &lt;a href=&quot;https://codigum.com/notas/vale-la-pena-migrar-a-rust/&quot;&gt;cinco preguntas antes de migrar&lt;/a&gt; ayudan a hacerla con honestidad.&lt;/p&gt;
&lt;h2 id=&quot;un-plan-de-90-dias&quot;&gt;Un plan de 90 días&lt;/h2&gt;
&lt;p&gt;Esto es lo que recomendamos para un equipo de 3 a 8 personas:&lt;/p&gt;
&lt;h3 id=&quot;dias-1-a-30-fundamentos&quot;&gt;Días 1 a 30: fundamentos&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Elegir &lt;strong&gt;un componente pequeño y medible&lt;/strong&gt;, sin plazos críticos.&lt;/li&gt;
&lt;li&gt;Seguir una ruta común, como &lt;a href=&quot;https://codigum.com/aprende/&quot;&gt;nuestras ocho guías&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Formar a dos personas primero, para que acompañen al resto.&lt;/li&gt;
&lt;li&gt;Instalar desde el día uno &lt;code&gt;clippy&lt;/code&gt;, &lt;code&gt;rustfmt&lt;/code&gt; y las &lt;a href=&quot;https://codigum.com/aprende/herramientas/&quot;&gt;herramientas del día a día&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;dias-31-a-60-produccion-en-pequeno&quot;&gt;Días 31 a 60: producción en pequeño&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Construir el componente con pruebas y métricas, como en &lt;a href=&quot;https://codigum.com/notas/microservicio-en-rust-rendimiento/&quot;&gt;este microservicio&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Revisar en pareja todo el código, y dedicar tiempo a leer los errores del compilador.&lt;/li&gt;
&lt;li&gt;Usar &lt;code&gt;.clone()&lt;/code&gt; sin culpa: la eficiencia se ajusta después.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;dias-61-a-90-evaluar&quot;&gt;Días 61 a 90: evaluar&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Desplegar con una salida gradual, y comparar con el sistema anterior.&lt;/li&gt;
&lt;li&gt;Medir tres cosas: tiempo de entrega, incidentes y recursos.&lt;/li&gt;
&lt;li&gt;Decidir con datos si Rust se extiende, se queda en ese componente o se abandona.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Abandonar también es un buen resultado, si sale barato y a tiempo.&lt;/p&gt;
&lt;h2 id=&quot;que-acelera-la-curva&quot;&gt;Qué acelera la curva&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Compilar con menos sufrimiento:&lt;/strong&gt; usa &lt;code&gt;cargo check&lt;/code&gt; mientras escribes, y &lt;a href=&quot;https://codigum.com/aprende/herramientas/&quot;&gt;bacon&lt;/a&gt; para ver errores al guardar.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mentoría en el código real:&lt;/strong&gt; un experto que revisa tus pull requests vale más que muchas horas de curso.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Empezar con un problema propio:&lt;/strong&gt; los ejercicios abstractos se olvidan.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Corrode, una consultora especializada, &lt;a rel=&quot;external&quot; href=&quot;https://corrode.dev/services/&quot;&gt;afirma&lt;/a&gt; que la formación permite llevar a un equipo al ritmo en unos 2 meses en lugar de 4. Es una cifra comercial, no un estudio, así que tómala como referencia.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Los 7 fallos de memoria más comunes, ilustrados</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/fallos-de-memoria-ilustrados/"/>
        <id>https://codigum.com/notas/fallos-de-memoria-ilustrados/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/fallos-de-memoria-ilustrados/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;Un fallo de memoria ocurre cuando un programa lee o escribe donde no debe, o en un momento en que no debe.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Imagina la memoria como una fila larga de casilleros numerados. Tu programa pide unos cuantos, guarda cosas en ellos y los devuelve cuando termina. Casi todo lo que puede salir mal se resume en tres preguntas: &lt;strong&gt;dónde&lt;/strong&gt; escribes, &lt;strong&gt;cuándo&lt;/strong&gt; usas lo que tienes y &lt;strong&gt;quién más&lt;/strong&gt; lo está tocando.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Familia&lt;/th&gt;&lt;th&gt;Qué se rompe&lt;/th&gt;&lt;th&gt;Fallos&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Espacio&lt;/td&gt;&lt;td&gt;Se usa un casillero fuera de lo reservado&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/#desbordamiento&quot;&gt;Desbordamiento de búfer&lt;/a&gt;, &lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/#lectura&quot;&gt;lectura fuera de límites&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Tiempo&lt;/td&gt;&lt;td&gt;Se usa un casillero que ya no es tuyo&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/#uaf&quot;&gt;Uso después de liberar&lt;/a&gt;, &lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/#doble&quot;&gt;doble liberación&lt;/a&gt;, &lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/#fuga&quot;&gt;fuga de memoria&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Valor&lt;/td&gt;&lt;td&gt;Se confía en algo que no existe&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/#nulo&quot;&gt;Puntero nulo&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Concurrencia&lt;/td&gt;&lt;td&gt;Dos hilos tocan lo mismo a la vez&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/#carrera&quot;&gt;Carrera de datos&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;No son rarezas de laboratorio. En el &lt;a rel=&quot;external&quot; href=&quot;https://cwe.mitre.org/top25/archive/2025/2025_cwe_top25.html&quot;&gt;CWE Top 25 de 2025&lt;/a&gt;, la escritura fuera de límites ocupa el puesto 5, el uso después de liberar el 7 y la lectura fuera de límites el 8. La &lt;a href=&quot;https://codigum.com/notas/que-es-seguridad-de-memoria/&quot;&gt;cifra del 70 %&lt;/a&gt; de Microsoft habla de esta misma familia.&lt;/p&gt;
&lt;h2 id=&quot;desbordamiento&quot;&gt;1. Desbordamiento de búfer (buffer overflow)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Analogía:&lt;/strong&gt; guardas tanto en tu casillero que lo que sobra invade el del vecino.&lt;/p&gt;
&lt;p&gt;Ocurre cuando se escribe más de lo que cabe en el espacio reservado. C no comprueba el tamaño por ti:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;c&quot;&gt;char nombre[8];
int es_admin = 0;
strcpy(nombre, entrada); // copia sin mirar cuánto cabe
&lt;/code&gt;&lt;/pre&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 244&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Antes, nombre tiene ocho espacios y a su lado está es_admin con valor cero. Al copiar doce letras, las cuatro últimas pisan es_admin, que deja de ser cero.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;12&quot; y=&quot;18&quot;&gt;Antes: dos variables, una junto a otra&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;12&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;50&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;88&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;126&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;164&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;202&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;240&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;278&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;316&quot; y=&quot;30&quot; width=&quot;148&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;390&quot; y=&quot;57.5&quot;&gt;es_admin = 0&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M12 80v7H312v-7&quot;/&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;162&quot; y=&quot;104&quot;&gt;nombre: 8 espacios&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;12&quot; y=&quot;146&quot;&gt;Después de copiar «María Gracia», 12 letras&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;12&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;29&quot; y=&quot;185.5&quot;&gt;M&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;50&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;67&quot; y=&quot;185.5&quot;&gt;a&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;88&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;105&quot; y=&quot;185.5&quot;&gt;r&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;126&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;143&quot; y=&quot;185.5&quot;&gt;í&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;164&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;181&quot; y=&quot;185.5&quot;&gt;a&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;202&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;219&quot; y=&quot;185.5&quot;&gt;·&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;240&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;257&quot; y=&quot;185.5&quot;&gt;G&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;278&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;295&quot; y=&quot;185.5&quot;&gt;r&lt;/text&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;316&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;333&quot; y=&quot;185.5&quot;&gt;a&lt;/text&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;354&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;371&quot; y=&quot;185.5&quot;&gt;c&lt;/text&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;392&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;409&quot; y=&quot;185.5&quot;&gt;i&lt;/text&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;430&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;447&quot; y=&quot;185.5&quot;&gt;a&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M12 208v7H312v-7&quot;/&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;162&quot; y=&quot;232&quot;&gt;lo reservado&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--bad&quot; d=&quot;M316 208v7H464v-7&quot;/&gt;&lt;text class=&quot;dg__t dg__mid dg__tbad&quot; x=&quot;390&quot; y=&quot;232&quot;&gt;es_admin ya no es 0&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Lo que sobra no desaparece: cae sobre lo que estaba al lado. Ilustración simplificada; la disposición real depende del compilador.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Si quien envía &lt;code&gt;entrada&lt;/code&gt; elige bien los bytes, puede cambiar datos del programa e incluso desviar su ejecución. Por eso este fallo acompaña a la seguridad informática desde hace décadas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;En Rust&lt;/strong&gt;, cada acceso por índice comprueba los límites. Si te pasas, el programa se detiene de forma controlada, sin pisar nada:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    let notas = vec![12, 15, 18];
    let i = notas.len();
    println!(&amp;quot;{}&amp;quot;, notas[i]); // pánico: index out of bounds
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Detenerse es mejor que corromper datos, pero en un servidor sigue siendo una caída: la &lt;a rel=&quot;external&quot; href=&quot;https://blog.cloudflare.com/18-november-2025-outage&quot;&gt;interrupción de Cloudflare de noviembre de 2025&lt;/a&gt; fue justamente un pánico en código Rust. Por eso conviene preguntar antes de acceder:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    let notas = vec![12, 15, 18];
    match notas.get(3) {
        Some(nota) =&amp;gt; println!(&amp;quot;{nota}&amp;quot;),
        None =&amp;gt; println!(&amp;quot;Esa posición no existe&amp;quot;),
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;lectura&quot;&gt;2. Lectura fuera de límites (out-of-bounds read)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Analogía:&lt;/strong&gt; pides ver tu casillero, y te muestran también los tres siguientes.&lt;/p&gt;
&lt;p&gt;Aquí no se daña nada, y justamente por eso es peligroso: el programa sigue funcionando mientras entrega lo que no debería.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 244&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Una fila de memoria con la palabra hola y, a su lado, una contraseña. Si se piden cuatro letras se recibe hola; si se piden doce, también se recibe la contraseña.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;12&quot; y=&quot;18&quot;&gt;Petición honesta: «devuélveme 4 letras»&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;12&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;29&quot; y=&quot;57.5&quot;&gt;h&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;50&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;67&quot; y=&quot;57.5&quot;&gt;o&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;88&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;105&quot; y=&quot;57.5&quot;&gt;l&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;126&quot; y=&quot;30&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;143&quot; y=&quot;57.5&quot;&gt;a&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;164&quot; y=&quot;30&quot; width=&quot;300&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;314&quot; y=&quot;57.5&quot;&gt;contraseña de otra persona&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M12 80v7H160v-7&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;12&quot; y=&quot;104&quot;&gt;recibe: hola&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;12&quot; y=&quot;146&quot;&gt;Petición maliciosa: «devuélveme 12»&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;12&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;29&quot; y=&quot;185.5&quot;&gt;h&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;50&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;67&quot; y=&quot;185.5&quot;&gt;o&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;88&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;105&quot; y=&quot;185.5&quot;&gt;l&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;126&quot; y=&quot;158&quot; width=&quot;34&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;143&quot; y=&quot;185.5&quot;&gt;a&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;164&quot; y=&quot;158&quot; width=&quot;300&quot; height=&quot;44&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;314&quot; y=&quot;185.5&quot;&gt;contraseña de otra persona&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--bad&quot; d=&quot;M12 208v7H464v-7&quot;/&gt;&lt;text class=&quot;dg__t dg__tbad&quot; x=&quot;12&quot; y=&quot;232&quot;&gt;recibe: hola y la contraseña&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;El programa confía en la cifra que le dan, y entrega lo que haya al lado. Nada falla ni deja rastro evidente.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;El caso más famoso es &lt;a rel=&quot;external&quot; href=&quot;https://heartbleed.com/&quot;&gt;Heartbleed&lt;/a&gt; (CVE-2014-0160), en OpenSSL. Un atacante podía indicar una longitud mayor que la real y recibir el contenido de la memoria del servidor, incluidas claves y contraseñas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;En Rust&lt;/strong&gt; se aplica la misma comprobación de límites del caso anterior: un rebanado o un índice fuera de rango no devuelve memoria ajena.&lt;/p&gt;
&lt;h2 id=&quot;uaf&quot;&gt;3. Uso después de liberar (use-after-free)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Analogía:&lt;/strong&gt; devuelves la llave del casillero, pero conservas una copia. Otra persona ya guardó allí sus cosas.&lt;/p&gt;
&lt;p&gt;Es uno de los fallos más explotados, porque quien ataca puede intentar controlar qué ocupa esa memoria.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 172&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Primero s apunta a tu dato. Luego la memoria se libera, pero s sigue apuntando ahí. Al final, otra parte del programa la reutiliza y s lee datos ajenos.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;18&quot;&gt;1. Reservas&lt;/text&gt;&lt;text class=&quot;dg__c&quot; x=&quot;74&quot; y=&quot;50&quot;&gt;s&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M74 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;0&quot; y=&quot;88&quot; width=&quot;148&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;74&quot; y=&quot;117.5&quot;&gt;tu dato&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;74&quot; y=&quot;160&quot;&gt;s es válido&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;166&quot; y=&quot;18&quot;&gt;2. Liberas&lt;/text&gt;&lt;text class=&quot;dg__c&quot; x=&quot;240&quot; y=&quot;50&quot;&gt;s&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--bad&quot; d=&quot;M240 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__free&quot; x=&quot;166&quot; y=&quot;88&quot; width=&quot;148&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__mm&quot; x=&quot;240&quot; y=&quot;117.5&quot;&gt;libre&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__tbad&quot; x=&quot;240&quot; y=&quot;160&quot;&gt;s sigue apuntando&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;332&quot; y=&quot;18&quot;&gt;3. Otro la reutiliza&lt;/text&gt;&lt;text class=&quot;dg__c&quot; x=&quot;406&quot; y=&quot;50&quot;&gt;s&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--bad&quot; d=&quot;M406 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;332&quot; y=&quot;88&quot; width=&quot;148&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;406&quot; y=&quot;117.5&quot;&gt;dato ajeno&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__tbad&quot; x=&quot;406&quot; y=&quot;160&quot;&gt;s lee datos ajenos&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;El puntero parece válido, pero la memoria ya pertenece a otra parte del programa.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Este código en C compila, aunque es incorrecto:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;c&quot;&gt;char *s = malloc(16);
free(s);
s[0] = &amp;#39;x&amp;#39;; // uso después de liberar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;En Rust&lt;/strong&gt; el compilador comprueba que ninguna referencia viva más que el dato. Es el trabajo de los &lt;a href=&quot;https://codigum.com/aprende/lifetimes/&quot;&gt;tiempos de vida&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    let r;
    {
        let s = String::from(&amp;quot;hola&amp;quot;);
        r = &amp;amp;s;
    } // `s` se libera aquí
    println!(&amp;quot;{r}&amp;quot;); // error[E0597]: `s` does not live long enough
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El error aparece antes de ejecutar el programa.&lt;/p&gt;
&lt;h2 id=&quot;doble&quot;&gt;4. Doble liberación (double free)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Analogía:&lt;/strong&gt; dos personas devuelven la misma llave. El registro de casilleros queda con una entrada falsa, y más tarde el mismo casillero se asigna a dos personas.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 172&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Dos punteros, a y b, apuntan al mismo bloque. Se libera con a. Al liberar también con b, el bloque se devuelve dos veces y el gestor de memoria queda en un estado inconsistente.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;18&quot;&gt;1. Dos punteros&lt;/text&gt;&lt;text class=&quot;dg__c&quot; x=&quot;46&quot; y=&quot;50&quot;&gt;a&lt;/text&gt;&lt;text class=&quot;dg__c&quot; x=&quot;102&quot; y=&quot;50&quot;&gt;b&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M46 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M102 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;0&quot; y=&quot;88&quot; width=&quot;148&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;74&quot; y=&quot;117.5&quot;&gt;bloque&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;74&quot; y=&quot;160&quot;&gt;un solo bloque&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;166&quot; y=&quot;18&quot;&gt;2. free(a)&lt;/text&gt;&lt;text class=&quot;dg__c dg__mm&quot; x=&quot;212&quot; y=&quot;50&quot;&gt;a&lt;/text&gt;&lt;text class=&quot;dg__c&quot; x=&quot;268&quot; y=&quot;50&quot;&gt;b&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--off&quot; d=&quot;M212 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;path class=&quot;dg__ptr dg__ptr--bad&quot; d=&quot;M268 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__free&quot; x=&quot;166&quot; y=&quot;88&quot; width=&quot;148&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__mm&quot; x=&quot;240&quot; y=&quot;117.5&quot;&gt;devuelto&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__tbad&quot; x=&quot;240&quot; y=&quot;160&quot;&gt;b no se enteró&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;332&quot; y=&quot;18&quot;&gt;3. free(b)&lt;/text&gt;&lt;text class=&quot;dg__c dg__mm&quot; x=&quot;378&quot; y=&quot;50&quot;&gt;a&lt;/text&gt;&lt;text class=&quot;dg__c dg__mm&quot; x=&quot;434&quot; y=&quot;50&quot;&gt;b&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--off&quot; d=&quot;M378 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;path class=&quot;dg__ptr dg__ptr--bad&quot; d=&quot;M434 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;332&quot; y=&quot;88&quot; width=&quot;148&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;406&quot; y=&quot;117.5&quot;&gt;devuelto dos veces&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__tbad&quot; x=&quot;406&quot; y=&quot;160&quot;&gt;el gestor se corrompe&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Dos variables creen ser responsables del mismo bloque, y ambas lo devuelven.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;pre&gt;&lt;code data-lang=&quot;c&quot;&gt;char *a = malloc(16);
char *b = a;
free(a);
free(b); // el mismo bloque, por segunda vez
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;En Rust&lt;/strong&gt; cada valor tiene &lt;a href=&quot;https://codigum.com/aprende/ownership/&quot;&gt;un único dueño&lt;/a&gt;, así que solo uno puede liberarlo. Intentarlo dos veces no compila:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    let s = String::from(&amp;quot;hola&amp;quot;);
    drop(s);
    drop(s); // error[E0382]: use of moved value: `s`
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;nulo&quot;&gt;5. Puntero nulo (null pointer dereference)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Analogía:&lt;/strong&gt; te dan una llave con un número de casillero que no existe.&lt;/p&gt;
&lt;p&gt;Su creador, Tony Hoare, lo llamó su &quot;error de mil millones de dólares&quot;. El problema de fondo es que cualquier referencia podría no apuntar a nada, y nada en el tipo lo avisa. En C suele terminar en una caída. En Java aparece como &lt;code&gt;NullPointerException&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 198&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;En C, un puntero puede ser nulo sin que nada lo indique, y leerlo detiene el programa. En Rust, Option obliga a contemplar los dos casos: Some y None.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;18&quot;&gt;En C: la ausencia no se ve&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;249&quot; y=&quot;18&quot;&gt;En Rust: la ausencia es un tipo&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;60&quot; y=&quot;34&quot; width=&quot;110&quot; height=&quot;42&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;115&quot; y=&quot;60.5&quot;&gt;cliente&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--bad&quot; d=&quot;M115 78V110m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;0&quot; y=&quot;114&quot; width=&quot;231&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;115.5&quot; y=&quot;143.5&quot;&gt;NULL: aquí no hay nada&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__tbad&quot; x=&quot;115.5&quot; y=&quot;186&quot;&gt;leerlo detiene el programa&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;309.5&quot; y=&quot;34&quot; width=&quot;110&quot; height=&quot;42&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;364.5&quot; y=&quot;60.5&quot;&gt;Option&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M364.5 76V92H304.5V110m-5-7 5 7 5-7M364.5 92H424.5V110m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;249&quot; y=&quot;114&quot; width=&quot;107&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;302.5&quot; y=&quot;143.5&quot;&gt;Some&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;372&quot; y=&quot;114&quot; width=&quot;108&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;426&quot; y=&quot;143.5&quot;&gt;None&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;364.5&quot; y=&quot;186&quot;&gt;el compilador exige los dos casos&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;El problema no es que algo falte, sino que nada avise de que puede faltar.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;En Rust&lt;/strong&gt; las referencias seguras nunca son nulas. Lo que puede faltar se declara con &lt;code&gt;Option&lt;/code&gt;, y el compilador impide usarlo sin revisar:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn buscar(id: u32) -&amp;gt; Option&amp;lt;String&amp;gt; {
    if id == 1 { Some(String::from(&amp;quot;Ana&amp;quot;)) } else { None }
}

fn main() {
    match buscar(7) {
        Some(nombre) =&amp;gt; println!(&amp;quot;{}&amp;quot;, nombre.len()),
        None =&amp;gt; println!(&amp;quot;Cliente no encontrado&amp;quot;),
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lo explicamos paso a paso en la guía de &lt;a href=&quot;https://codigum.com/aprende/option-result/&quot;&gt;Option y Result&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;carrera&quot;&gt;6. Carrera de datos (data race)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Analogía:&lt;/strong&gt; dos cajeros consultan el mismo saldo a la vez, y cada uno anota su propio resultado. Una de las dos operaciones desaparece.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 224&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Dos hilos leen el saldo 100 casi a la vez. El hilo A escribe 110, luego el hilo B escribe 80. El resultado debió ser 90: la suma de diez se perdió.&quot;&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;130.5&quot; y=&quot;18&quot;&gt;Paso 1&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;229.5&quot; y=&quot;18&quot;&gt;Paso 2&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;328.5&quot; y=&quot;18&quot;&gt;Paso 3&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;427.5&quot; y=&quot;18&quot;&gt;Paso 4&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;61&quot;&gt;Hilo A&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;84&quot; y=&quot;34&quot; width=&quot;93&quot; height=&quot;42&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs dg__on&quot; x=&quot;130.5&quot; y=&quot;60.5&quot;&gt;lee 100&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;282&quot; y=&quot;34&quot; width=&quot;93&quot; height=&quot;42&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs dg__on&quot; x=&quot;328.5&quot; y=&quot;60.5&quot;&gt;escribe 110&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;113&quot;&gt;Hilo B&lt;/text&gt;&lt;rect class=&quot;dg__cellb&quot; x=&quot;183&quot; y=&quot;86&quot; width=&quot;93&quot; height=&quot;42&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;229.5&quot; y=&quot;112.5&quot;&gt;lee 100&lt;/text&gt;&lt;rect class=&quot;dg__cellb&quot; x=&quot;381&quot; y=&quot;86&quot; width=&quot;93&quot; height=&quot;42&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;427.5&quot; y=&quot;112.5&quot;&gt;escribe 80&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;173&quot;&gt;saldo&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;84&quot; y=&quot;146&quot; width=&quot;93&quot; height=&quot;42&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;130.5&quot; y=&quot;172.5&quot;&gt;100&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;183&quot; y=&quot;146&quot; width=&quot;93&quot; height=&quot;42&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;229.5&quot; y=&quot;172.5&quot;&gt;100&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;282&quot; y=&quot;146&quot; width=&quot;93&quot; height=&quot;42&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;328.5&quot; y=&quot;172.5&quot;&gt;110&lt;/text&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;381&quot; y=&quot;146&quot; width=&quot;93&quot; height=&quot;42&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;427.5&quot; y=&quot;172.5&quot;&gt;80&lt;/text&gt;&lt;path class=&quot;dg__grid&quot; d=&quot;M0 136H480&quot;/&gt;&lt;text class=&quot;dg__t dg__tbad&quot; x=&quot;480&quot; y=&quot;212&quot; text-anchor=&quot;end&quot;&gt;Debió quedar 90: el +10 se perdió&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Ninguno de los dos hilos hizo algo incorrecto por sí solo. El error está en el momento.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Es el fallo más difícil de reproducir: puede aparecer una vez cada millón de ejecuciones, y desaparecer justo cuando lo depuras.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;En Rust&lt;/strong&gt; este código no compila, porque el hilo podría tocar &lt;code&gt;saldo&lt;/code&gt; mientras el programa principal también lo usa:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::thread;

fn main() {
    let mut saldo = 100;
    let hilo = thread::spawn(|| saldo += 10); // error[E0373]
    saldo -= 20;
    hilo.join().unwrap();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La versión correcta hace explícito cómo se comparte el dato. Sin tomar el candado, ni siquiera se puede acceder al valor:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let saldo = Arc::new(Mutex::new(100));
    let copia = Arc::clone(&amp;amp;saldo);

    let hilo = thread::spawn(move || *copia.lock().unwrap() += 10);
    *saldo.lock().unwrap() -= 20;

    hilo.join().unwrap();
    println!(&amp;quot;{}&amp;quot;, saldo.lock().unwrap()); // siempre 90
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust evita las carreras de datos, pero &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/ch16-03-shared-state.html&quot;&gt;no evita los interbloqueos&lt;/a&gt; ni otros errores de lógica en la concurrencia.&lt;/p&gt;
&lt;h2 id=&quot;fuga&quot;&gt;7. Fuga de memoria (memory leak)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Analogía:&lt;/strong&gt; pides casilleros y nunca los devuelves. Nadie resulta afectado hoy, hasta que no quedan casilleros.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 178&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Una línea escalonada de memoria ocupada que sube con el tiempo hasta acercarse al límite de memoria.&quot;&gt;&lt;path class=&quot;dg__axisl&quot; d=&quot;M30 16V170H476&quot;/&gt;&lt;path class=&quot;dg__limit&quot; d=&quot;M30 36H476&quot;/&gt;&lt;text class=&quot;dg__t dg__tbad&quot; x=&quot;36&quot; y=&quot;28&quot;&gt;límite de memoria&lt;/text&gt;&lt;path class=&quot;dg__stroke&quot; d=&quot;M34 150H72V138H110V126H148V114H186V104H224V92H262V80H300V70H338V58H376V48H414V44H452V40H470&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;476&quot; y=&quot;162&quot; text-anchor=&quot;end&quot;&gt;tiempo&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;250&quot; y=&quot;128&quot;&gt;cada ciclo olvida devolver un poco&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Nada se corrompe. El servicio solo crece, hasta que el sistema lo detiene. Ilustración, no medición.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;No es una vulnerabilidad de memoria en sentido estricto, pero tumba servicios. Y aquí Rust no promete tanto: el Libro lo dice con claridad, &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/ch15-06-reference-cycles.html&quot;&gt;las fugas son seguras en memoria&lt;/a&gt; y evitarlas por completo no es una de sus garantías. Son difíciles de provocar por accidente, porque la memoria se libera sola al salir de alcance, pero un ciclo de &lt;code&gt;Rc&lt;/code&gt; lo consigue:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::cell::RefCell;
use std::rc::Rc;

struct Nodo {
    siguiente: RefCell&amp;lt;Option&amp;lt;Rc&amp;lt;Nodo&amp;gt;&amp;gt;&amp;gt;,
}

fn main() {
    let a = Rc::new(Nodo { siguiente: RefCell::new(None) });
    let b = Rc::new(Nodo { siguiente: RefCell::new(Some(Rc::clone(&amp;amp;a))) });
    *a.siguiente.borrow_mut() = Some(Rc::clone(&amp;amp;b));
    // `a` y `b` se sostienen entre sí: nunca se liberan
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Los lenguajes con recolector de basura también pueden fugar memoria, si una lista o una caché conserva referencias que ya nadie necesita.&lt;/p&gt;
&lt;h2 id=&quot;comparacion-por-lenguaje&quot;&gt;Comparación por lenguaje&lt;/h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Fallo&lt;/th&gt;&lt;th&gt;C y C++&lt;/th&gt;&lt;th&gt;Java, C#, Go, Python&lt;/th&gt;&lt;th&gt;Rust seguro&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Desbordamiento de búfer&lt;/td&gt;&lt;td&gt;Posible&lt;/td&gt;&lt;td&gt;Error en ejecución&lt;/td&gt;&lt;td&gt;Pánico en ejecución&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Lectura fuera de límites&lt;/td&gt;&lt;td&gt;Posible&lt;/td&gt;&lt;td&gt;Error en ejecución&lt;/td&gt;&lt;td&gt;Pánico en ejecución&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Uso después de liberar&lt;/td&gt;&lt;td&gt;Posible&lt;/td&gt;&lt;td&gt;Evitado por el recolector&lt;/td&gt;&lt;td&gt;No compila&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Doble liberación&lt;/td&gt;&lt;td&gt;Posible&lt;/td&gt;&lt;td&gt;No aplica&lt;/td&gt;&lt;td&gt;No compila&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Puntero nulo&lt;/td&gt;&lt;td&gt;Posible&lt;/td&gt;&lt;td&gt;Error en ejecución&lt;/td&gt;&lt;td&gt;No compila&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Carrera de datos&lt;/td&gt;&lt;td&gt;Posible&lt;/td&gt;&lt;td&gt;Posible&lt;/td&gt;&lt;td&gt;No compila&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Fuga de memoria&lt;/td&gt;&lt;td&gt;Posible&lt;/td&gt;&lt;td&gt;Posible&lt;/td&gt;&lt;td&gt;Difícil, pero posible&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&quot;Rust seguro&quot; importa: el código marcado como &lt;code&gt;unsafe&lt;/code&gt; queda bajo tu responsabilidad, y los errores de lógica o de autorización siguen siendo posibles en cualquier lenguaje.&lt;/p&gt;
&lt;p&gt;Java, C#, Go y Python resuelven buena parte de esta tabla con un recolector de basura, a cambio de trabajo en tiempo de ejecución. Ese costo tiene sus propias consecuencias, y las explicamos en &lt;a href=&quot;https://codigum.com/notas/recolector-de-basura-vs-rust/&quot;&gt;Recolector de basura vs. Rust&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>21 pisos por las escaleras: la historia del origen de Rust</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/historia-origen-de-rust/"/>
        <id>https://codigum.com/notas/historia-origen-de-rust/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/historia-origen-de-rust/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;Rust nació de una frustración cotidiana: un ascensor que no funcionaba porque su software había fallado.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Es 2006. Graydon Hoare tiene 29 años, trabaja como programador en Mozilla y vive en Vancouver. Al volver a su apartamento encuentra el ascensor fuera de servicio. Su software se ha colgado, y no es la primera vez.&lt;/p&gt;
&lt;p&gt;Vive en el piso 21.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 238&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;A la izquierda, un ascensor fuera de servicio por un fallo de software. A la derecha, una escalera de veintiún pisos por la que sube Graydon Hoare.&quot;&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;16&quot; y=&quot;14&quot; width=&quot;86&quot; height=&quot;196&quot; rx=&quot;10&quot;/&gt;&lt;path class=&quot;dg__ptr dg__ptr--off&quot; d=&quot;M59 14V150&quot;/&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;28&quot; y=&quot;150&quot; width=&quot;62&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;59&quot; y=&quot;179.5&quot;&gt;fuera&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__tbad&quot; x=&quot;59&quot; y=&quot;228&quot;&gt;software colgado&lt;/text&gt;&lt;path class=&quot;dg__stroke&quot; d=&quot;M126 204h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8h15v-8.8&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;126&quot; y=&quot;226&quot;&gt;piso 1&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;444&quot; y=&quot;12&quot; text-anchor=&quot;end&quot;&gt;piso 21&lt;/text&gt;&lt;circle class=&quot;dg__dot&quot; cx=&quot;300&quot; cy=&quot;104&quot; r=&quot;6&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;290&quot; y=&quot;84&quot; text-anchor=&quot;end&quot;&gt;Hoare, a pie&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;2006, Vancouver. Según MIT Technology Review, no era la primera vez que ese ascensor fallaba.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Mientras sube, según contó &lt;a rel=&quot;external&quot; href=&quot;https://www.technologyreview.com/2023/02/14/1067869/rust-worlds-fastest-growing-programming-language/&quot;&gt;MIT Technology Review&lt;/a&gt;, piensa que es ridículo que quienes trabajan con computadoras no puedan hacer un ascensor que funcione sin colgarse. Y sabe por dónde suele venir el problema: muchas de esas caídas nacen en cómo un programa usa la memoria.&lt;/p&gt;
&lt;p&gt;Software como ese suele estar escrito en lenguajes como C o C++, que permiten crear código pequeño y rápido, pero también facilitan esos errores. Podría haberse quedado en una queja. Hoare hizo otra cosa: abrió su portátil y empezó a diseñar un lenguaje que permitiera escribir código pequeño y rápido sin esos fallos.&lt;/p&gt;
&lt;h2 id=&quot;un-proyecto-personal&quot;&gt;Un proyecto personal&lt;/h2&gt;
&lt;p&gt;Durante tres años, Rust fue un proyecto paralelo. El nombre tampoco salió de un comité. Viene de un grupo de hongos, las royas, que a Hoare le parecían &lt;a href=&quot;https://codigum.com/aprende/miscelanea/&quot;&gt;sobrediseñados para sobrevivir&lt;/a&gt;. En el fondo, era una declaración de intenciones.&lt;/p&gt;
&lt;h2 id=&quot;mozilla-apuesta-por-el&quot;&gt;Mozilla apuesta por él&lt;/h2&gt;
&lt;p&gt;En 2009, Mozilla decidió patrocinar el proyecto. Sus directivos vieron que Rust podía ayudarles a construir un mejor motor de navegador, un software complejo y propenso a fallos de memoria peligrosos. La empresa empezó a pagarle a un equipo para trabajar en él a tiempo completo.&lt;/p&gt;
&lt;h2 id=&quot;el-dia-que-rust-dejo-atras-el-recolector-de-basura&quot;&gt;El día que Rust dejó atrás el recolector de basura&lt;/h2&gt;
&lt;p&gt;Este es quizá el detalle más sorprendente: &lt;strong&gt;Rust tuvo recolector de basura&lt;/strong&gt;. En 2013, el equipo lo retiró del lenguaje.&lt;/p&gt;
&lt;p&gt;Fue una decisión enorme. Sin él, Rust dependía por completo de sus reglas de propiedad y préstamo para garantizar la seguridad de la memoria. A cambio, ganaba algo que casi ningún lenguaje seguro ofrecía: &lt;a href=&quot;https://codigum.com/notas/recolector-de-basura-vs-rust/&quot;&gt;rendimiento predecible, sin un proceso ajeno trabajando en segundo plano&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ese mismo año, Hoare se apartó del proyecto. Lo que había empezado como una idea personal ya era de una comunidad.&lt;/p&gt;
&lt;h2 id=&quot;de-la-version-1-0-al-kernel-de-linux&quot;&gt;De la versión 1.0 al kernel de Linux&lt;/h2&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 238&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Línea de tiempo de Rust: 2006, Hoare empieza a diseñarlo; 2009, Mozilla lo patrocina; 2013, se retira el recolector de basura; 2015, versión 1.0; 2017, llega a Firefox; 2021, nace la Rust Foundation; 2025, Linux concluye su experimento.&quot;&gt;&lt;path class=&quot;dg__axisl&quot; d=&quot;M70 12V216&quot;/&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;17&quot;&gt;2006&lt;/text&gt;&lt;circle class=&quot;dg__dot&quot; cx=&quot;70&quot; cy=&quot;12&quot; r=&quot;5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;90&quot; y=&quot;17&quot;&gt;Hoare empieza a diseñarlo en su portátil&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;51&quot;&gt;2009&lt;/text&gt;&lt;circle class=&quot;dg__dot&quot; cx=&quot;70&quot; cy=&quot;46&quot; r=&quot;5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;90&quot; y=&quot;51&quot;&gt;Mozilla patrocina el proyecto&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;85&quot;&gt;2013&lt;/text&gt;&lt;circle class=&quot;dg__dot&quot; cx=&quot;70&quot; cy=&quot;80&quot; r=&quot;5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;90&quot; y=&quot;85&quot;&gt;Se retira el recolector de basura&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;119&quot;&gt;2015&lt;/text&gt;&lt;circle class=&quot;dg__dot&quot; cx=&quot;70&quot; cy=&quot;114&quot; r=&quot;5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;90&quot; y=&quot;119&quot;&gt;Rust 1.0, el 15 de mayo&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;153&quot;&gt;2017&lt;/text&gt;&lt;circle class=&quot;dg__dot&quot; cx=&quot;70&quot; cy=&quot;148&quot; r=&quot;5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;90&quot; y=&quot;153&quot;&gt;Rust llega al motor CSS de Firefox&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;187&quot;&gt;2021&lt;/text&gt;&lt;circle class=&quot;dg__dot&quot; cx=&quot;70&quot; cy=&quot;182&quot; r=&quot;5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;90&quot; y=&quot;187&quot;&gt;Nace la Rust Foundation&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;221&quot;&gt;2025&lt;/text&gt;&lt;circle class=&quot;dg__dot&quot; cx=&quot;70&quot; cy=&quot;216&quot; r=&quot;5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;90&quot; y=&quot;221&quot;&gt;Linux da por concluido su experimento con Rust&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Diecinueve años entre un ascensor averiado y el kernel de Linux.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;La versión 1.0 llegó el 15 de mayo de 2015. Era una promesa de estabilidad: el código escrito entonces seguiría compilando. Luego vinieron las pruebas de fuego. En 2017, una parte del motor de Firefox ya estaba en Rust. En 2020, Dropbox y Discord contaban sus reescrituras. En 2021, AWS, Google, Huawei, Microsoft y Mozilla crearon la &lt;a rel=&quot;external&quot; href=&quot;https://rustfoundation.org/&quot;&gt;Rust Foundation&lt;/a&gt;, y el lenguaje dejó de depender de una sola empresa.&lt;/p&gt;
&lt;p&gt;Hoy Rust está en &lt;a href=&quot;https://codigum.com/por-que-rust/quien-usa-rust/&quot;&gt;Android, Windows, Linux y la infraestructura de la nube&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;lo-que-nos-deja-esta-historia&quot;&gt;Lo que nos deja esta historia&lt;/h2&gt;
&lt;p&gt;Vale la pena mirar la historia completa. Rust no surgió de un plan estratégico ni de un laboratorio, sino de alguien que se negó a aceptar que el software tuviera que fallar así.&lt;/p&gt;
&lt;p&gt;Hay también una lección más incómoda. Los &lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/&quot;&gt;fallos de memoria&lt;/a&gt; no eran un secreto en 2006. Todo el sector los conocía y los trataba como el costo inevitable de hacer software rápido. Rust demostró que ese costo no era inevitable: se podía tener control y seguridad a la vez.&lt;/p&gt;
&lt;p&gt;Cada vez que un error así se evita antes de compilar, alguien, en algún lugar, no tiene que subir veintiún pisos a pie.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Huella de carbono del software: cómo el código eficiente reduce emisiones</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/huella-de-carbono-del-software/"/>
        <id>https://codigum.com/notas/huella-de-carbono-del-software/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/huella-de-carbono-del-software/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;Cada instrucción innecesaria se paga tres veces: en latencia, en la factura y en electricidad.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;El software no tiene chimenea, pero decide cuántos servidores se encienden y durante cuánto tiempo. Por eso ingeniería y sostenibilidad suelen perseguir lo mismo: hacer el mismo trabajo con menos recursos.&lt;/p&gt;
&lt;h2 id=&quot;del-codigo-a-las-emisiones&quot;&gt;Del código a las emisiones&lt;/h2&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 98&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Una cadena de cinco pasos: el código determina CPU y memoria, estas determinan los servidores, luego la electricidad y finalmente las emisiones.&quot;&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;0&quot; y=&quot;10&quot; width=&quot;78&quot; height=&quot;52&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs dg__on&quot; x=&quot;39&quot; y=&quot;41.5&quot;&gt;Código&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M81 36H97.5m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;100.5&quot; y=&quot;10&quot; width=&quot;78&quot; height=&quot;52&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;139.5&quot; y=&quot;41.5&quot;&gt;CPU y RAM&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M181.5 36H198m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;201&quot; y=&quot;10&quot; width=&quot;78&quot; height=&quot;52&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;240&quot; y=&quot;41.5&quot;&gt;Servidores&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M282 36H298.5m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;301.5&quot; y=&quot;10&quot; width=&quot;78&quot; height=&quot;52&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;340.5&quot; y=&quot;41.5&quot;&gt;Electricidad&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M382.5 36H399m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;402&quot; y=&quot;10&quot; width=&quot;78&quot; height=&quot;52&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;441&quot; y=&quot;41.5&quot;&gt;Emisiones&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;0&quot; y=&quot;88&quot;&gt;Menos trabajo aquí…&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;480&quot; y=&quot;88&quot; text-anchor=&quot;end&quot;&gt;…se traduce en menos aquí&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;El código está al inicio de la cadena, y por eso influye en todo lo que viene después.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;La &lt;a rel=&quot;external&quot; href=&quot;https://learn.greensoftware.foundation/energy-efficiency&quot;&gt;Green Software Foundation&lt;/a&gt; lo plantea así: la electricidad es un indicador indirecto del carbono, de modo que el objetivo es usar la menor energía posible por unidad de trabajo.&lt;/p&gt;
&lt;h2 id=&quot;el-tamano-del-problema&quot;&gt;El tamaño del problema&lt;/h2&gt;
&lt;p&gt;Según la &lt;a rel=&quot;external&quot; href=&quot;https://www.iea.org/reports/energy-and-ai/executive-summary&quot;&gt;Agencia Internacional de la Energía&lt;/a&gt;, los centros de datos consumieron unos 415 TWh en 2024, alrededor del 1,5 % de la electricidad mundial. Su proyección es que se duplique con creces hacia 2030.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 92&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Consumo eléctrico de los centros de datos: 415 teravatios hora en 2024 y una proyección de 945 en 2030.&quot;&gt;&lt;text class=&quot;dg__t&quot; x=&quot;46&quot; y=&quot;29&quot; text-anchor=&quot;end&quot;&gt;2024&lt;/text&gt;&lt;rect class=&quot;dg__fgc&quot; x=&quot;56&quot; y=&quot;8&quot; width=&quot;149.312&quot; height=&quot;30&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;213.312&quot; y=&quot;29&quot;&gt;415 TWh&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;46&quot; y=&quot;71&quot; text-anchor=&quot;end&quot;&gt;2030&lt;/text&gt;&lt;rect class=&quot;dg__fgc2&quot; x=&quot;56&quot; y=&quot;50&quot; width=&quot;340&quot; height=&quot;30&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;404&quot; y=&quot;71&quot;&gt;945 TWh&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Consumo eléctrico de los centros de datos. El dato de 2030 es una proyección de la AIE.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;como-estimar-tu-huella&quot;&gt;Cómo estimar tu huella&lt;/h2&gt;
&lt;p&gt;La cuenta básica cabe en una línea:&lt;/p&gt;
&lt;aside class=&quot;callout callout--nota&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;La fórmula&lt;/p&gt;
&lt;p&gt;Emisiones = energía del servidor × PUE × intensidad de carbono de la red&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;El &lt;strong&gt;PUE&lt;/strong&gt; mide el consumo adicional del centro de datos, como la refrigeración: con 1,5, cada 10 kWh de cómputo consumen 15 kWh de la red. La &lt;strong&gt;intensidad de carbono&lt;/strong&gt; indica cuánto CO₂ emite cada kWh, y cambia mucho según el país.&lt;/p&gt;
&lt;p&gt;Un ejemplo con valores supuestos: 20 servidores a 300 W, PUE de 1,5 y 0,4 kg de CO₂ por kWh.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Paso&lt;/th&gt;&lt;th&gt;Cálculo&lt;/th&gt;&lt;th&gt;Resultado&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Energía al año&lt;/td&gt;&lt;td&gt;20 × 0,3 kW × 8760 h&lt;/td&gt;&lt;td&gt;52 560 kWh&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Con el centro de datos&lt;/td&gt;&lt;td&gt;52 560 × 1,5&lt;/td&gt;&lt;td&gt;78 840 kWh&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Emisiones&lt;/td&gt;&lt;td&gt;78 840 × 0,4&lt;/td&gt;&lt;td&gt;31,5 t de CO₂&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Si el mismo trabajo se hace con 10 servidores, la cifra baja a unas 15,8 toneladas, y la factura de esos servidores también se reduce a la mitad. Es una simplificación: un servidor real no consume siempre lo mismo. Sirve para ver qué variables mandan.&lt;/p&gt;
&lt;h2 id=&quot;cuanto-influye-el-lenguaje&quot;&gt;¿Cuánto influye el lenguaje?&lt;/h2&gt;
&lt;p&gt;Sobre esto hay un dato muy citado, y conviene leerlo con cuidado. Un &lt;a rel=&quot;external&quot; href=&quot;https://greenlab.di.uminho.pt/wp-content/uploads/2017/10/sleFinal.pdf&quot;&gt;estudio de 2017&lt;/a&gt; comparó la energía de 27 lenguajes en diez problemas de referencia.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Lenguaje&lt;/th&gt;&lt;th&gt;Energía relativa a C&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;C&lt;/td&gt;&lt;td&gt;1,00&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Rust&lt;/td&gt;&lt;td&gt;1,03&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;C++&lt;/td&gt;&lt;td&gt;1,34&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Python&lt;/td&gt;&lt;td&gt;75,88&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Amazon lo llevó al debate público en &lt;a rel=&quot;external&quot; href=&quot;https://aws.amazon.com/blogs/opensource/sustainability-with-rust/&quot;&gt;Sustainability with Rust&lt;/a&gt;, de 2022. Allí señala que C y Rust fueron aproximadamente un 50 % más eficientes que Java y un 98 % más que Python, y sostiene que su adopción amplia podría reducir a la mitad la energía de cómputo. También cuenta el caso de Tenable, que al reescribir un componente de JavaScript a Rust redujo un 75 % el uso de CPU y un 95 % el de memoria.&lt;/p&gt;
&lt;p&gt;Ahora, lo que esas cifras no dicen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Son programas de referencia, no tu sistema.&lt;/strong&gt; Tu aplicación probablemente pasa mucho tiempo esperando a la red o a la base de datos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;La energía sigue al tiempo de ejecución.&lt;/strong&gt; Un &lt;a rel=&quot;external&quot; href=&quot;https://arxiv.org/abs/2410.05460&quot;&gt;estudio de 2024&lt;/a&gt; concluye que el lenguaje no tiene un efecto significativo en la energía más allá del tiempo de ejecución, y critica que estos rankings se interpreten como causa directa.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon no midió energía en esos casos.&lt;/strong&gt; La infiere de CPU, memoria y servidores. Además, patrocina el proyecto Rust.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;El ahorro puede consumirse.&lt;/strong&gt; Si el cómputo se abarata, es posible que se use más.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La conclusión práctica es más sobria y más útil: &lt;strong&gt;Rust ayuda cuando reduce los servidores que necesitas&lt;/strong&gt;. Si no los reduce, no cambia tu huella.&lt;/p&gt;
&lt;h2 id=&quot;por-donde-empezar&quot;&gt;Por dónde empezar&lt;/h2&gt;
&lt;p&gt;Ordenadas por lo que suelen aportar, estas son las palancas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;No hacer trabajo innecesario.&lt;/strong&gt; Tareas duplicadas, datos que nadie consulta, ambientes encendidos sin uso.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ajustar la capacidad.&lt;/strong&gt; Un servidor &lt;a rel=&quot;external&quot; href=&quot;https://learn.greensoftware.foundation/energy-efficiency&quot;&gt;desocupado sigue consumiendo&lt;/a&gt;. Es mejor menos máquinas, mejor aprovechadas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mejorar lo que más se ejecuta.&lt;/strong&gt; Un algoritmo mejor, menos copias de datos, buena caché.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cambiar el lenguaje de la ruta crítica.&lt;/strong&gt; Aquí entra Rust, junto con el &lt;a href=&quot;https://codigum.com/notas/recolector-de-basura-vs-rust/&quot;&gt;ahorro de memoria frente a un recolector de basura&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elegir dónde y cuándo ejecutar.&lt;/strong&gt; Una región con energía más limpia, o tareas por lotes en mejores horarios.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alargar la vida del hardware.&lt;/strong&gt; Si tu software pide menos, los equipos duran más, y fabricarlos también emite.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;un-argumento-de-negocio&quot;&gt;Un argumento de negocio&lt;/h2&gt;
&lt;p&gt;Rara vez hace falta un presupuesto de sostenibilidad para esto. La eficiencia se paga sola, porque el mismo cambio aparece en la factura de la nube. Y si tu empresa reporta emisiones, tendrás una cifra medida que mostrar, en lugar de una promesa.&lt;/p&gt;
&lt;p&gt;Eso sí, mide antes de anunciar. Un ahorro de CPU es un dato. Una reducción de emisiones es un cálculo con supuestos, y debe presentarse como tal.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Tu primer microservicio en Rust, y cuánto rinde de verdad</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/microservicio-en-rust-rendimiento/"/>
        <id>https://codigum.com/notas/microservicio-en-rust-rendimiento/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/microservicio-en-rust-rendimiento/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;Rust no siempre gana en latencia. Donde gana sin discusión es en memoria, y eso se nota en la factura.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Hay muchas comparaciones de rendimiento en internet. Esta la hicimos nosotros, con código que puedes copiar. Construimos un microservicio pequeño, lo medimos frente a tres alternativas y publicamos también lo que no favorece a Rust.&lt;/p&gt;
&lt;h2 id=&quot;que-vamos-a-construir&quot;&gt;Qué vamos a construir&lt;/h2&gt;
&lt;p&gt;Un servicio que devuelve clientes en JSON, con un endpoint de salud, registro estructurado y apagado ordenado. Son las piezas básicas de un servicio de verdad.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 78&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Una petición llega a Actix Web, que la enruta, busca el dato en un mapa en memoria y responde en JSON.&quot;&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;0&quot; y=&quot;6&quot; width=&quot;102&quot; height=&quot;64&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;51&quot; y=&quot;33&quot;&gt;Petición&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__ts&quot; x=&quot;51&quot; y=&quot;54&quot;&gt;GET /clientes/1&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M105 38H123m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;126&quot; y=&quot;6&quot; width=&quot;102&quot; height=&quot;64&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__c dg__cs dg__on&quot; x=&quot;177&quot; y=&quot;33&quot;&gt;Actix Web&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__ts dg__on&quot; x=&quot;177&quot; y=&quot;54&quot;&gt;enruta y valida&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M231 38H249m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;252&quot; y=&quot;6&quot; width=&quot;102&quot; height=&quot;64&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;303&quot; y=&quot;33&quot;&gt;Datos&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__ts&quot; x=&quot;303&quot; y=&quot;54&quot;&gt;HashMap&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M357 38H375m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;378&quot; y=&quot;6&quot; width=&quot;102&quot; height=&quot;64&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;429&quot; y=&quot;33&quot;&gt;Respuesta&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__ts&quot; x=&quot;429&quot; y=&quot;54&quot;&gt;JSON&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;El ejemplo no usa base de datos: así medimos el servicio y no otra cosa.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;requisitos&quot;&gt;Requisitos&lt;/h2&gt;
&lt;p&gt;Necesitas &lt;a href=&quot;https://codigum.com/aprende/instalar-rust/&quot;&gt;Rust instalado&lt;/a&gt;. Crea el proyecto:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;bash&quot;&gt;cargo new clientes
cd clientes
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;las-dependencias&quot;&gt;Las dependencias&lt;/h2&gt;
&lt;p&gt;Este es el &lt;code&gt;Cargo.toml&lt;/code&gt;. El perfil de compilación final importa: optimiza al máximo y deja un binario pequeño.&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;toml&quot;&gt;[package]
name = &amp;quot;clientes&amp;quot;
version = &amp;quot;0.1.0&amp;quot;
edition = &amp;quot;2024&amp;quot;

[dependencies]
actix-web = &amp;quot;4&amp;quot;
anyhow = &amp;quot;1&amp;quot;
clap = { version = &amp;quot;4&amp;quot;, features = [&amp;quot;derive&amp;quot;] }
mimalloc = { version = &amp;quot;0.1&amp;quot;, default-features = false }
serde = { version = &amp;quot;1&amp;quot;, features = [&amp;quot;derive&amp;quot;] }
serde_json = &amp;quot;1&amp;quot;
thiserror = &amp;quot;2&amp;quot;
tokio = { version = &amp;quot;1&amp;quot;, features = [&amp;quot;full&amp;quot;] }
tracing = &amp;quot;0.1&amp;quot;
tracing-actix-web = &amp;quot;0.7&amp;quot;
tracing-subscriber = { version = &amp;quot;0.3&amp;quot;, features = [&amp;quot;env-filter&amp;quot;] }

[build-dependencies]
chrono = { version = &amp;quot;0.4&amp;quot;, features = [&amp;quot;clock&amp;quot;] }

[profile.release]
opt-level = 3
lto = true
codegen-units = 1
panic = &amp;quot;abort&amp;quot;
strip = true
debug = 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cada pieza cumple una función:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Paquete&lt;/th&gt;&lt;th&gt;Para qué sirve&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;actix-web&lt;/code&gt;&lt;/td&gt;&lt;td&gt;El servidor HTTP&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;tokio&lt;/code&gt;&lt;/td&gt;&lt;td&gt;El entorno asíncrono&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;serde&lt;/code&gt;, &lt;code&gt;serde_json&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Convertir a JSON&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;tracing&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Registro estructurado&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;clap&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Argumentos de línea de comandos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;anyhow&lt;/code&gt;, &lt;code&gt;thiserror&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Manejo de errores&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;mimalloc&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Un &lt;a rel=&quot;external&quot; href=&quot;https://github.com/microsoft/mimalloc&quot;&gt;asignador de memoria&lt;/a&gt; rápido&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;el-codigo&quot;&gt;El código&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;src/cli.rs&lt;/code&gt; define los argumentos. Con &lt;code&gt;-v&lt;/code&gt; muestra la versión y con &lt;code&gt;config&lt;/code&gt; imprime la configuración:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use clap::{Parser, Subcommand};

pub const PKG_NAME: &amp;amp;str = env!(&amp;quot;CARGO_PKG_NAME&amp;quot;);
pub const PKG_VERSION: &amp;amp;str = env!(&amp;quot;CARGO_PKG_VERSION&amp;quot;);
pub const GIT_HASH: &amp;amp;str = env!(&amp;quot;GIT_HASH&amp;quot;);
pub const BUILD_DATE: &amp;amp;str = env!(&amp;quot;BUILD_DATE&amp;quot;);
pub const PKG_ARCH: &amp;amp;str = env!(&amp;quot;ARCH&amp;quot;);

#[derive(Parser)]
#[command(name = &amp;quot;clientes&amp;quot;, about = &amp;quot;Microservicio de ejemplo&amp;quot;, disable_version_flag = true)]
pub struct Cli {
    /// Muestra la versión y termina
    #[arg(short = &amp;#39;v&amp;#39;, long = &amp;quot;version&amp;quot;)]
    pub version: bool,

    #[command(subcommand)]
    pub command: Option&amp;lt;Commands&amp;gt;,
}

#[derive(Subcommand)]
pub enum Commands {
    /// Muestra la configuración como JSON
    Config,
}

pub fn get_version() -&amp;gt; String {
    format!(&amp;quot;{PKG_NAME} {PKG_VERSION} ({GIT_HASH} {BUILD_DATE}) {PKG_ARCH}&amp;quot;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;src/main.rs&lt;/code&gt; contiene el servicio. Fíjate en los errores: &lt;code&gt;AppError&lt;/code&gt; define qué respuesta recibe el cliente, y un cliente inexistente devuelve un 404 en JSON. Al recibir &lt;code&gt;SIGTERM&lt;/code&gt; o Ctrl+C, el servicio termina lo que tiene en curso antes de apagarse.&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;mod cli;

use std::collections::HashMap;

use actix_web::{App, HttpResponse, HttpServer, ResponseError, get, http::StatusCode, web};
use anyhow::{Context, Result};
use clap::Parser;
use serde::Serialize;
use tracing_actix_web::TracingLogger;

use cli::{Cli, Commands, get_version};

#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;

#[derive(Serialize)]
struct Config {
    host: String,
    port: u16,
    workers: usize,
}

impl Default for Config {
    fn default() -&amp;gt; Self {
        let workers = std::env::var(&amp;quot;WORKERS&amp;quot;)
            .ok()
            .and_then(|v| v.parse().ok())
            .unwrap_or_else(num_cpus);
        let port = std::env::var(&amp;quot;PORT&amp;quot;)
            .ok()
            .and_then(|v| v.parse().ok())
            .unwrap_or(8080);
        Self { host: &amp;quot;127.0.0.1&amp;quot;.into(), port, workers }
    }
}

fn num_cpus() -&amp;gt; usize {
    std::thread::available_parallelism().map_or(1, |n| n.get())
}

#[derive(Clone, Serialize)]
struct Cliente {
    id: u32,
    nombre: String,
    activo: bool,
}

#[derive(Debug, Serialize)]
struct ErrorBody {
    error: String,
    message: String,
}

#[derive(Debug, thiserror::Error)]
enum AppError {
    #[error(&amp;quot;cliente {0} no encontrado&amp;quot;)]
    NoEncontrado(u32),
}

impl ResponseError for AppError {
    fn status_code(&amp;amp;self) -&amp;gt; StatusCode {
        StatusCode::NOT_FOUND
    }

    fn error_response(&amp;amp;self) -&amp;gt; HttpResponse {
        let status = self.status_code();
        HttpResponse::build(status).json(ErrorBody {
            error: status.canonical_reason().unwrap_or(&amp;quot;error&amp;quot;).to_string(),
            message: self.to_string(),
        })
    }
}

type Clientes = web::Data&amp;lt;HashMap&amp;lt;u32, Cliente&amp;gt;&amp;gt;;

#[get(&amp;quot;/salud&amp;quot;)]
async fn salud() -&amp;gt; &amp;amp;&amp;#39;static str {
    &amp;quot;ok&amp;quot;
}

#[get(&amp;quot;/clientes/{id}&amp;quot;)]
async fn cliente(id: web::Path&amp;lt;u32&amp;gt;, datos: Clientes) -&amp;gt; Result&amp;lt;web::Json&amp;lt;Cliente&amp;gt;, AppError&amp;gt; {
    let id = id.into_inner();
    let cliente = datos.get(&amp;amp;id).cloned().ok_or(AppError::NoEncontrado(id))?;
    Ok(web::Json(cliente))
}

fn init_logger() {
    tracing_subscriber::fmt()
        .with_env_filter(
            tracing_subscriber::EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new(&amp;quot;info&amp;quot;)),
        )
        .with_target(true)
        .with_thread_ids(false)
        .compact()
        .init();
}

async fn shutdown(handle: actix_web::dev::ServerHandle) {
    use tokio::signal::unix::{SignalKind, signal};

    let mut sigterm = signal(SignalKind::terminate()).expect(&amp;quot;no se pudo escuchar SIGTERM&amp;quot;);
    tokio::select! {
        _ = sigterm.recv() =&amp;gt; {}
        _ = tokio::signal::ctrl_c() =&amp;gt; {}
    }
    tracing::info!(&amp;quot;shutdown signal received, initiating graceful shutdown&amp;quot;);
    handle.stop(true).await;
}

#[actix_web::main]
async fn main() -&amp;gt; Result&amp;lt;()&amp;gt; {
    let cli = Cli::parse();
    if cli.version {
        println!(&amp;quot;{}&amp;quot;, get_version());
        return Ok(());
    }

    let config = Config::default();
    if let Some(Commands::Config) = cli.command {
        println!(&amp;quot;{}&amp;quot;, serde_json::to_string_pretty(&amp;amp;config)?);
        return Ok(());
    }

    init_logger();
    tracing::info!(version = %get_version(), &amp;quot;starting service&amp;quot;);

    let total: u32 = std::env::var(&amp;quot;CLIENTES&amp;quot;)
        .ok()
        .and_then(|v| v.parse().ok())
        .unwrap_or(1000);
    let datos: HashMap&amp;lt;u32, Cliente&amp;gt; = (1..=total)
        .map(|id| (id, Cliente { id, nombre: format!(&amp;quot;Cliente {id}&amp;quot;), activo: id % 2 == 0 }))
        .collect();
    let datos = web::Data::new(datos);

    let servidor = HttpServer::new(move || {
        App::new()
            .wrap(TracingLogger::default())
            .app_data(datos.clone())
            .service(salud)
            .service(cliente)
    })
    .workers(config.workers)
    .disable_signals()
    .bind((config.host.as_str(), config.port))
    .with_context(|| format!(&amp;quot;failed to bind to port {}&amp;quot;, config.port))?
    .run();

    tracing::info!(host = %config.host, port = config.port, &amp;quot;server running&amp;quot;);
    tokio::spawn(shutdown(servidor.handle()));
    servidor.await.context(&amp;quot;server error&amp;quot;)?;
    tracing::info!(&amp;quot;server shutdown complete&amp;quot;);
    Ok(())
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Por último, &lt;code&gt;build.rs&lt;/code&gt; graba en el binario el commit, la fecha y la arquitectura, para saber siempre qué versión corre en producción:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::process::Command;

fn main() {
    let git_hash = Command::new(&amp;quot;git&amp;quot;)
        .args([&amp;quot;rev-parse&amp;quot;, &amp;quot;--short&amp;quot;, &amp;quot;HEAD&amp;quot;])
        .output()
        .ok()
        .and_then(|output| String::from_utf8(output.stdout).ok())
        .map(|s| s.trim().to_string())
        .filter(|s| !s.is_empty())
        .unwrap_or_else(|| &amp;quot;unknown&amp;quot;.to_string());
    let build_date = chrono::Utc::now().format(&amp;quot;%Y-%m-%d&amp;quot;).to_string();
    let arch = std::env::var(&amp;quot;CARGO_CFG_TARGET_ARCH&amp;quot;).unwrap_or_else(|_| &amp;quot;unknown&amp;quot;.to_string());

    println!(&amp;quot;cargo:rustc-env=GIT_HASH={git_hash}&amp;quot;);
    println!(&amp;quot;cargo:rustc-env=BUILD_DATE={build_date}&amp;quot;);
    println!(&amp;quot;cargo:rustc-env=ARCH={arch}&amp;quot;);
    println!(&amp;quot;cargo:rerun-if-changed=.git/HEAD&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;compilar-y-probar&quot;&gt;Compilar y probar&lt;/h2&gt;
&lt;pre&gt;&lt;code data-lang=&quot;bash&quot;&gt;cargo build --release
./target/release/clientes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Desde otra terminal, con &lt;a href=&quot;https://codigum.com/aprende/herramientas/&quot;&gt;xh o curl&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;bash&quot;&gt;xh :8080/clientes/500
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code data-lang=&quot;json&quot;&gt;{ &amp;quot;id&amp;quot;: 500, &amp;quot;nombre&amp;quot;: &amp;quot;Cliente 500&amp;quot;, &amp;quot;activo&amp;quot;: true }
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;como-lo-medimos&quot;&gt;Cómo lo medimos&lt;/h2&gt;
&lt;p&gt;Para generar carga usamos &lt;a rel=&quot;external&quot; href=&quot;https://github.com/hatoo/oha&quot;&gt;oha&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;bash&quot;&gt;oha -z 10s -c 64 http://127.0.0.1:8080/clientes/500
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Escribimos el mismo endpoint en Go, Node.js y Python, y en todos usamos un solo núcleo, para que la comparación sea justa. Node y Python ya funcionan así por defecto. Rust y Go se limitaron con &lt;code&gt;WORKERS=1&lt;/code&gt; y &lt;code&gt;GOMAXPROCS=1&lt;/code&gt;.&lt;/p&gt;
&lt;details class=&quot;detalle&quot;&gt;
&lt;summary&gt;Ver el método completo y el código de las alternativas&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Equipo:&lt;/strong&gt; MacBook Pro con Apple M4 Max, 14 núcleos y 36 GB de memoria, macOS. El generador de carga corrió en la misma máquina.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Versiones:&lt;/strong&gt; Rust 1.96.1 con Actix Web 4.18.1, Go 1.27.3 con &lt;code&gt;net/http&lt;/code&gt;, Node.js 26.8.1 con &lt;code&gt;node:http&lt;/code&gt;, Python 3.9.6 con FastAPI 0.128.8 y Uvicorn 0.39.0.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prueba de capacidad:&lt;/strong&gt; 10 s, 64 conexiones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prueba de carga fija:&lt;/strong&gt; 15 s a 2000 peticiones por segundo, con corrección de latencia.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Repeticiones:&lt;/strong&gt; tres por servicio; mostramos la mediana.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sin&lt;/strong&gt; TLS, base de datos ni red real.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Go:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;go&quot;&gt;package main

import (
	&amp;quot;encoding/json&amp;quot;
	&amp;quot;fmt&amp;quot;
	&amp;quot;net/http&amp;quot;
	&amp;quot;os&amp;quot;
	&amp;quot;strconv&amp;quot;
)

type Cliente struct {
	ID     int    `json:&amp;quot;id&amp;quot;`
	Nombre string `json:&amp;quot;nombre&amp;quot;`
	Activo bool   `json:&amp;quot;activo&amp;quot;`
}

func main() {
	datos := map[int]Cliente{}
	total, err := strconv.Atoi(os.Getenv(&amp;quot;CLIENTES&amp;quot;))
	if err != nil {
		total = 1000
	}
	for id := 1; id &amp;lt;= total; id++ {
		datos[id] = Cliente{id, fmt.Sprintf(&amp;quot;Cliente %d&amp;quot;, id), id%2 == 0}
	}
	http.HandleFunc(&amp;quot;GET /clientes/{id}&amp;quot;, func(w http.ResponseWriter, r *http.Request) {
		id, _ := strconv.Atoi(r.PathValue(&amp;quot;id&amp;quot;))
		c, ok := datos[id]
		w.Header().Set(&amp;quot;Content-Type&amp;quot;, &amp;quot;application/json&amp;quot;)
		if !ok {
			w.WriteHeader(http.StatusNotFound)
			w.Write([]byte(`{&amp;quot;error&amp;quot;:&amp;quot;no encontrado&amp;quot;}`))
			return
		}
		json.NewEncoder(w).Encode(c)
	})
	http.ListenAndServe(&amp;quot;127.0.0.1:8082&amp;quot;, nil)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Node.js:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;js&quot;&gt;import http from &amp;#39;node:http&amp;#39;;
const datos = new Map();
const total = Number(process.env.CLIENTES ?? 1000);
for (let id = 1; id &amp;lt;= total; id++) datos.set(id, { id, nombre: `Cliente ${id}`, activo: id % 2 === 0 });
http.createServer((req, res) =&amp;gt; {
  const m = req.url.match(/^\/clientes\/(\d+)$/);
  const c = m &amp;amp;&amp;amp; datos.get(Number(m[1]));
  if (!c) { res.writeHead(404, { &amp;#39;content-type&amp;#39;: &amp;#39;application/json&amp;#39; }); return res.end(&amp;#39;{&amp;quot;error&amp;quot;:&amp;quot;no encontrado&amp;quot;}&amp;#39;); }
  res.writeHead(200, { &amp;#39;content-type&amp;#39;: &amp;#39;application/json&amp;#39; });
  res.end(JSON.stringify(c));
}).listen(8081, &amp;#39;127.0.0.1&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Python:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;from fastapi import FastAPI, HTTPException

app = FastAPI()
datos = {i: {&amp;quot;id&amp;quot;: i, &amp;quot;nombre&amp;quot;: f&amp;quot;Cliente {i}&amp;quot;, &amp;quot;activo&amp;quot;: i % 2 == 0} for i in range(1, 1001)}


@app.get(&amp;quot;/clientes/{id}&amp;quot;)
async def cliente(id: int):
    if id not in datos:
        raise HTTPException(status_code=404, detail=&amp;quot;no encontrado&amp;quot;)
    return datos[id]
&lt;/code&gt;&lt;/pre&gt;
&lt;/details&gt;
&lt;h2 id=&quot;primer-resultado-un-servicio-pequeno&quot;&gt;Primer resultado: un servicio pequeño&lt;/h2&gt;
&lt;p&gt;Con 1000 registros, esto es lo que obtuvimos:&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 402&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Con un núcleo: capacidad de 104 567 peticiones por segundo en Rust, 101 489 en Go, 90 580 en Node.js y 14 024 en Python. Memoria de 4,7, 15,5, 65,9 y 38,5 megabytes. CPU de 6,6, 8, 8,1 y 34,5 por ciento.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;14&quot;&gt;Capacidad máxima, peticiones por segundo&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;39&quot; text-anchor=&quot;end&quot;&gt;Rust&lt;/text&gt;&lt;rect class=&quot;dg__frust&quot; x=&quot;80&quot; y=&quot;26&quot; width=&quot;320&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;408&quot; y=&quot;39.5&quot;&gt;104 567&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;63&quot; text-anchor=&quot;end&quot;&gt;Go&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;50&quot; width=&quot;310.581&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;398.581&quot; y=&quot;63.5&quot;&gt;101 489&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;87&quot; text-anchor=&quot;end&quot;&gt;Node.js&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;74&quot; width=&quot;277.196&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;365.196&quot; y=&quot;87.5&quot;&gt;90 580&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;111&quot; text-anchor=&quot;end&quot;&gt;Python&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;98&quot; width=&quot;42.9168&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;130.917&quot; y=&quot;111.5&quot;&gt;14 024&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;152&quot;&gt;Memoria, MB&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;177&quot; text-anchor=&quot;end&quot;&gt;Rust&lt;/text&gt;&lt;rect class=&quot;dg__frust&quot; x=&quot;80&quot; y=&quot;164&quot; width=&quot;22.8225&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;110.822&quot; y=&quot;177.5&quot;&gt;4,7&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;201&quot; text-anchor=&quot;end&quot;&gt;Go&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;188&quot; width=&quot;75.2656&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;163.266&quot; y=&quot;201.5&quot;&gt;15,5&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;225&quot; text-anchor=&quot;end&quot;&gt;Node.js&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;212&quot; width=&quot;320&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;408&quot; y=&quot;225.5&quot;&gt;65,9&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;249&quot; text-anchor=&quot;end&quot;&gt;Python&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;236&quot; width=&quot;186.95&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;274.95&quot; y=&quot;249.5&quot;&gt;38,5&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;290&quot;&gt;CPU a 2000 peticiones por segundo, %&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;315&quot; text-anchor=&quot;end&quot;&gt;Rust&lt;/text&gt;&lt;rect class=&quot;dg__frust&quot; x=&quot;80&quot; y=&quot;302&quot; width=&quot;61.2174&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;149.217&quot; y=&quot;315.5&quot;&gt;6,6&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;339&quot; text-anchor=&quot;end&quot;&gt;Go&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;326&quot; width=&quot;74.2029&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;162.203&quot; y=&quot;339.5&quot;&gt;8,0&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;363&quot; text-anchor=&quot;end&quot;&gt;Node.js&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;350&quot; width=&quot;75.1304&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;163.13&quot; y=&quot;363.5&quot;&gt;8,1&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;387&quot; text-anchor=&quot;end&quot;&gt;Python&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;374&quot; width=&quot;320&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;408&quot; y=&quot;387.5&quot;&gt;34,5&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Medición propia: mediana de tres ejecuciones con un núcleo y 1000 registros. Mayor es mejor en capacidad; menor es mejor en memoria y CPU.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Con 1 núcleo&lt;/th&gt;&lt;th&gt;Rust&lt;/th&gt;&lt;th&gt;Go&lt;/th&gt;&lt;th&gt;Node.js&lt;/th&gt;&lt;th&gt;Python&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Capacidad máxima (pet/s)&lt;/td&gt;&lt;td&gt;104 567&lt;/td&gt;&lt;td&gt;101 489&lt;/td&gt;&lt;td&gt;90 580&lt;/td&gt;&lt;td&gt;14 024&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Memoria (MB)&lt;/td&gt;&lt;td&gt;4,7&lt;/td&gt;&lt;td&gt;15,5&lt;/td&gt;&lt;td&gt;65,9&lt;/td&gt;&lt;td&gt;38,5&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;CPU a 2000 pet/s&lt;/td&gt;&lt;td&gt;6,6 %&lt;/td&gt;&lt;td&gt;8,0 %&lt;/td&gt;&lt;td&gt;8,1 %&lt;/td&gt;&lt;td&gt;34,5 %&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Latencia p50 a 2000 pet/s (ms)&lt;/td&gt;&lt;td&gt;0,13&lt;/td&gt;&lt;td&gt;0,11&lt;/td&gt;&lt;td&gt;0,12&lt;/td&gt;&lt;td&gt;0,39&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Latencia p99 a 2000 pet/s (ms)&lt;/td&gt;&lt;td&gt;1,72&lt;/td&gt;&lt;td&gt;1,27&lt;/td&gt;&lt;td&gt;1,27&lt;/td&gt;&lt;td&gt;3,64&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Tamaño del binario (MB)&lt;/td&gt;&lt;td&gt;3,4&lt;/td&gt;&lt;td&gt;9,4&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Lo que dicen estos números:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;En latencia no hay ganador.&lt;/strong&gt; A carga moderada, Rust, Go y Node.js están empatados. Las diferencias del p99 entran en el ruido de la medición.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;La capacidad está cerca.&lt;/strong&gt; Rust, Go y Node.js superan las 90 000 peticiones por segundo en un núcleo. Muy pocos servicios llegan a eso.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;La memoria es la gran diferencia:&lt;/strong&gt; Rust usa un tercio que Go y unas catorce veces menos que Node.js.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python queda atrás, pero no es lento para muchos casos.&lt;/strong&gt; Sigue atendiendo 14 000 peticiones por segundo. Si haces veinte, da lo mismo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Conviene decirlo sin rodeos: si este fuera tu sistema, &lt;strong&gt;ninguna de estas cifras justifica por sí sola una migración&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;segundo-resultado-muchos-datos-en-memoria&quot;&gt;Segundo resultado: muchos datos en memoria&lt;/h2&gt;
&lt;p&gt;Aquí es donde se separan los caminos. Repetimos la prueba con &lt;strong&gt;5 millones de registros&lt;/strong&gt; en memoria y 20 000 peticiones por segundo, durante 25 a 30 segundos. Es el caso difícil para un recolector, como &lt;a href=&quot;https://codigum.com/notas/recolector-de-basura-vs-rust/&quot;&gt;explicamos en esta nota&lt;/a&gt;.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 216&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Con cinco millones de registros, Rust usa 408 megabytes, Go 865 y Node.js 875. La latencia p99 con un núcleo es de 4,7 milisegundos en Rust, 111 en Go y 2,3 en Node.js.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;14&quot;&gt;Memoria real con 5 millones de registros, MB&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;39&quot; text-anchor=&quot;end&quot;&gt;Rust&lt;/text&gt;&lt;rect class=&quot;dg__frust&quot; x=&quot;80&quot; y=&quot;26&quot; width=&quot;149.211&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;237.211&quot; y=&quot;39.5&quot;&gt;408&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;63&quot; text-anchor=&quot;end&quot;&gt;Go&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;50&quot; width=&quot;316.343&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;404.343&quot; y=&quot;63.5&quot;&gt;865&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;87&quot; text-anchor=&quot;end&quot;&gt;Node.js&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;74&quot; width=&quot;320&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;408&quot; y=&quot;87.5&quot;&gt;875&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;128&quot;&gt;p99 con 1 núcleo, ms (mediana de cuatro)&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;153&quot; text-anchor=&quot;end&quot;&gt;Rust&lt;/text&gt;&lt;rect class=&quot;dg__frust&quot; x=&quot;80&quot; y=&quot;140&quot; width=&quot;13.5495&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;101.55&quot; y=&quot;153.5&quot;&gt;4,7&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;177&quot; text-anchor=&quot;end&quot;&gt;Go&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;164&quot; width=&quot;320&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;408&quot; y=&quot;177.5&quot;&gt;111,0&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;70&quot; y=&quot;201&quot; text-anchor=&quot;end&quot;&gt;Node.js&lt;/text&gt;&lt;rect class=&quot;dg__fbar&quot; x=&quot;80&quot; y=&quot;188&quot; width=&quot;6.63063&quot; height=&quot;18&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;94.6306&quot; y=&quot;201.5&quot;&gt;2,3&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Medición propia. Menor es mejor. Rust gana en memoria; Node.js, en latencia con un núcleo.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;5 millones de registros&lt;/th&gt;&lt;th&gt;Rust&lt;/th&gt;&lt;th&gt;Go&lt;/th&gt;&lt;th&gt;Node.js&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Memoria real (MB)&lt;/td&gt;&lt;td&gt;408&lt;/td&gt;&lt;td&gt;865&lt;/td&gt;&lt;td&gt;875&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;p99 con 1 núcleo (ms)&lt;/td&gt;&lt;td&gt;2,2 a 10,9&lt;/td&gt;&lt;td&gt;81 a 127&lt;/td&gt;&lt;td&gt;2,1 a 2,9&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;p99.9 con 1 núcleo (ms)&lt;/td&gt;&lt;td&gt;6,8 a 37&lt;/td&gt;&lt;td&gt;152 a 206&lt;/td&gt;&lt;td&gt;5,6 a 28&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;p99 con 4 núcleos (ms)&lt;/td&gt;&lt;td&gt;2,3&lt;/td&gt;&lt;td&gt;2,6&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;p99.9 con 4 núcleos (ms)&lt;/td&gt;&lt;td&gt;5,3&lt;/td&gt;&lt;td&gt;17,4&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Mostramos rangos porque hicimos cuatro ejecuciones con un núcleo, y variaron bastante. Con cuatro núcleos hicimos solo una, de modo que esas cifras son orientativas.&lt;/p&gt;
&lt;p&gt;Este resultado nos parece más útil que uno que solo elogie a Rust:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Go con un núcleo sufre.&lt;/strong&gt; Su p99 sube a más de 80 ms, unas 40 veces lo normal. Es lo que predice su &lt;a rel=&quot;external&quot; href=&quot;https://tip.golang.org/doc/gc-guide&quot;&gt;guía oficial&lt;/a&gt;: el recolector recorre los datos vivos y necesita CPU. Con un solo núcleo, compite con las peticiones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Con 4 núcleos, casi desaparece.&lt;/strong&gt; El p99 de Go baja a 2,6 ms. Antes de reescribir, a veces basta con darle CPU, aunque esos núcleos también se pagan.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Node.js sorprendió.&lt;/strong&gt; Su p99 igualó o superó al de Rust. Una explicación probable es que V8 &lt;a rel=&quot;external&quot; href=&quot;https://v8.dev/blog/trash-talk&quot;&gt;separa objetos jóvenes y viejos&lt;/a&gt;, y no recorre todos los datos en cada ciclo. No perfilamos este punto, así que tómalo como hipótesis. No todos los recolectores se comportan igual.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rust no fue el más estable en p99.&lt;/strong&gt; Varió de 2,2 a 10,9 ms, y no investigamos la causa. Su p99.9 fue el mejor en la prueba con cuatro núcleos, pero Node.js estuvo a su nivel en algunas ejecuciones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;La memoria se mantiene:&lt;/strong&gt; Rust necesitó menos de la mitad que Go y que Node.js para los mismos datos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Una lección sobre medir: &lt;code&gt;ps&lt;/code&gt; nos mostró 360 MB para Node.js, porque no contaba la memoria comprimida por macOS. Con &lt;code&gt;footprint&lt;/code&gt;, eran 875 MB. Por eso ese dato de la tabla difiere de lo que verías en &lt;code&gt;ps&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;que-significa-para-tu-negocio&quot;&gt;Qué significa para tu negocio&lt;/h2&gt;
&lt;p&gt;Si lo traducimos a decisiones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Servicios sencillos:&lt;/strong&gt; no migres por rendimiento. Cualquiera de estas opciones te sirve.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Muchas instancias pequeñas:&lt;/strong&gt; aquí la memoria pesa. Un servicio de 5 MB frente a uno de 66 MB cambia cuántos caben en un servidor, y &lt;a href=&quot;https://codigum.com/notas/huella-de-carbono-del-software/&quot;&gt;cuánta energía consumes&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Grandes datos en memoria con poca CPU:&lt;/strong&gt; ahí es donde un recolector puede dar picos, y donde Rust ofrece más margen.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python en la ruta crítica:&lt;/strong&gt; suele ser el cambio con más retorno, y no siempre exige reescribir todo. Mira &lt;a href=&quot;https://codigum.com/notas/migrar-de-python-a-rust/&quot;&gt;cómo migrar por partes&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;lo-que-esta-prueba-no-dice&quot;&gt;Lo que esta prueba no dice&lt;/h2&gt;
&lt;p&gt;Un benchmark es una foto, no un veredicto:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El endpoint casi no hace trabajo. Un sistema real pasa la mayor parte del tiempo en la base de datos y en la red.&lt;/li&gt;
&lt;li&gt;El generador de carga compartió máquina con el servicio, lo que añade ruido.&lt;/li&gt;
&lt;li&gt;macOS no es tu servidor de producción, y Python 3.9 no es la versión más reciente.&lt;/li&gt;
&lt;li&gt;Limitar a un núcleo favorece a Node.js y Python, que por defecto usan uno, y perjudica a Go, que está pensado para usar varios.&lt;/li&gt;
&lt;li&gt;No ajustamos parámetros como &lt;code&gt;GOGC&lt;/code&gt; ni la memoria de V8.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Por eso lo más valioso de esta nota no son las cifras, sino el método. Repite la prueba con tu endpoint, tus datos y tu carga.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Noticias de Rust: Bun, Ubuntu, Astro, Git y Linux lo adoptan</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/noticias-de-rust/"/>
        <id>https://codigum.com/notas/noticias-de-rust/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/noticias-de-rust/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;Rust dejó de ser una opción para proyectos nuevos: ahora está entrando en el software básico que todos usamos.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Si necesitas una foto de lo que está pasando con Rust, aquí va. Reunimos las noticias más importantes de 2025 y 2026, cada una con su fuente original, y aclaramos qué cambió de verdad, porque los titulares suelen exagerar.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Fecha&lt;/th&gt;&lt;th&gt;Noticia&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Oct. 2026&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#ubuntu&quot;&gt;Ubuntu 26.10 completa sus utilidades básicas en Rust&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Jul. 2026&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#bun&quot;&gt;Bun migra de Zig a Rust&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Jun. 2026&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#git&quot;&gt;Git activa Rust por defecto&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Jun. 2026&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#astro&quot;&gt;Astro 7 reescribe su compilador en Rust&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Abr. 2026&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#linux&quot;&gt;Linux 7.0 quita a Rust la etiqueta experimental&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Abr. 2026&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#pixel&quot;&gt;Rust llega al módem del Pixel 10&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Mar. 2026&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#astral&quot;&gt;Astral, creadora de uv y Ruff, acuerda unirse a OpenAI&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ene. 2026&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#whatsapp&quot;&gt;WhatsApp distribuye Rust a miles de millones de dispositivos&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2026&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#chrome&quot;&gt;Chrome retira FreeType de su motor&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Nov. 2025&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#android&quot;&gt;Android baja del 20 % en fallos de memoria&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Oct. 2025&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#next&quot;&gt;Turbopack, por defecto en Next.js&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Fines de 2025&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#apt&quot;&gt;APT anuncia que dependerá de Rust&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Sep. 2025&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#cloudflare&quot;&gt;Cloudflare reescribe su sistema central&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;ubuntu&quot;&gt;Ubuntu: las utilidades básicas ya están en Rust&lt;/h2&gt;
&lt;p&gt;Pocos comandos son tan básicos como &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;cp&lt;/code&gt; o &lt;code&gt;sudo&lt;/code&gt;. Ubuntu los está cambiando por versiones en Rust, y lo hizo por etapas.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ubuntu 25.10:&lt;/strong&gt; &lt;code&gt;sudo-rs&lt;/code&gt; pasó a ser el &lt;code&gt;sudo&lt;/code&gt; por defecto, y &lt;code&gt;rust-coreutils&lt;/code&gt; empezó a dar las utilidades básicas. &lt;code&gt;cp&lt;/code&gt;, &lt;code&gt;mv&lt;/code&gt; y &lt;code&gt;rm&lt;/code&gt; siguieron siendo de GNU por errores pendientes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ubuntu 26.04 LTS:&lt;/strong&gt; esos cambios llegaron a la versión de soporte extendido, la que usan muchos servidores. Sus notas &lt;a rel=&quot;external&quot; href=&quot;https://documentation.ubuntu.com/release-notes/26.04/summary-for-lts-users/&quot;&gt;mencionan&lt;/a&gt; mejoras importantes de rendimiento, por ejemplo en &lt;code&gt;base64&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ubuntu 26.10:&lt;/strong&gt; publicado el 15 de octubre de 2026, &lt;a rel=&quot;external&quot; href=&quot;https://documentation.ubuntu.com/release-notes/26.10/&quot;&gt;ya ejecuta sus utilidades básicas por completo&lt;/a&gt; sobre &lt;code&gt;uutils&lt;/code&gt;, incluidos &lt;code&gt;cp&lt;/code&gt;, &lt;code&gt;mv&lt;/code&gt; y &lt;code&gt;rm&lt;/code&gt;. También suma Sequoia PGP, una implementación de OpenPGP en Rust, a su archivo principal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Por qué importa:&lt;/strong&gt; son programas de hace décadas, instalados en millones de máquinas. El matiz es que &lt;code&gt;gpg&lt;/code&gt; sigue disponible, y Ubuntu documenta cómo volver a las versiones de GNU. No fue un cambio sin dificultades: por eso tomó varias versiones.&lt;/p&gt;
&lt;h2 id=&quot;bun&quot;&gt;Bun: de Zig a Rust en semanas&lt;/h2&gt;
&lt;p&gt;Es probablemente la noticia más llamativa del año. &lt;a rel=&quot;external&quot; href=&quot;https://bun.com/blog/bun-in-rust&quot;&gt;Bun&lt;/a&gt;, un entorno de ejecución de JavaScript, anunció en julio de 2026 que dejaba Zig: la versión 1.3.14 fue la última en ese lenguaje, y la 1.4 es la primera en Rust. Bun pertenece a Anthropic desde diciembre de 2025.&lt;/p&gt;
&lt;p&gt;La razón no fue el rendimiento, sino la clase de errores. Muchos de sus fallos eran usos después de liberar, dobles liberaciones y memoria olvidada en rutas de error, &lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/&quot;&gt;los mismos que ilustramos aquí&lt;/a&gt;. Como resume el artículo: los errores del compilador son mejor ciclo de retroalimentación que una guía de estilo.&lt;/p&gt;
&lt;p&gt;Las cifras que publicó Bun:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Medida&lt;/th&gt;&lt;th&gt;Resultado&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Código original&lt;/td&gt;&lt;td&gt;535 496 líneas de Zig&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Código en Rust&lt;/td&gt;&lt;td&gt;Unas 780 000 líneas, cerca del 4 % en &lt;code&gt;unsafe&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Rendimiento HTTP&lt;/td&gt;&lt;td&gt;Entre 2,8 % y 4,8 % mejor&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Tamaño del binario&lt;/td&gt;&lt;td&gt;Cerca de 20 % menor&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Memoria en una prueba de 2000 compilaciones&lt;/td&gt;&lt;td&gt;De 6745 MB a 609 MB&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Regresiones conocidas&lt;/td&gt;&lt;td&gt;19, todas corregidas&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Lo que hay que leer con cuidado:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La migración fue una traducción masiva, apoyada en asistentes de IA y en su suite de pruebas. Según Bun, tomó 11 días y cerca de USD 165 000 en API, frente a un estimado de tres ingenieros durante un año. Son cifras de la propia empresa, cuya dueña vende esa IA.&lt;/li&gt;
&lt;li&gt;Cerca del 20 % de Bun sigue en C++, y sigue usando JavaScriptCore, BoringSSL y SQLite. No todo está en Rust.&lt;/li&gt;
&lt;li&gt;Una traducción directa no equivale a código bien diseñado, y 19 regresiones son un recordatorio de que estos cambios tienen costo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lo analizamos desde otro ángulo en &lt;a href=&quot;https://codigum.com/notas/rust-y-codigo-generado-por-ia/&quot;&gt;Rust y código generado por IA&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;git&quot;&gt;Git: Rust pasa a ser requisito&lt;/h2&gt;
&lt;p&gt;Git, la herramienta que usa casi todo desarrollador, está adoptando Rust de forma gradual. Según &lt;a rel=&quot;external&quot; href=&quot;https://git-scm.com/docs/BreakingChanges&quot;&gt;su documentación&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Git 2.49:&lt;/strong&gt; empezó la adopción, de forma opcional.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git 2.55:&lt;/strong&gt; activó Rust por defecto. Si falta en la máquina que compila, la compilación falla, aunque todavía se puede desactivar.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git 3.0:&lt;/strong&gt; Rust será obligatorio para compilar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;El matiz:&lt;/strong&gt; esto afecta a quien compila Git, no a quien lo usa. No es una reescritura: el proyecto avanza por partes, y prepara el código &lt;code&gt;xdiff&lt;/code&gt;. Además, Git aclara que evaluará el impacto en las distribuciones, y que podría aplazar la exigencia.&lt;/p&gt;
&lt;h2 id=&quot;astro&quot;&gt;Astro 7: un compilador nuevo&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://astro.build/blog/astro-7/&quot;&gt;Astro 7&lt;/a&gt; salió el 22 de junio de 2026 con un compilador &lt;code&gt;.astro&lt;/code&gt; reescrito en Rust, que reemplaza al anterior en Go. Su proceso de Markdown también pasó a Sätteri, escrito en Rust, y Vite 8 incorpora Rolldown como empaquetador.&lt;/p&gt;
&lt;p&gt;Algunos titulares dicen que Astro &quot;migró su núcleo a Rust&quot;, y conviene precisarlo: migraron piezas clave, mientras que la configuración, los complementos y tu código siguen en JavaScript o TypeScript.&lt;/p&gt;
&lt;p&gt;El dato más interesante es otro. Las compilaciones completas mejoraron entre 15 % y 61 %, pero el compilador nuevo por sí solo aportó cerca del 6 % en la documentación de Astro, porque, según el equipo, rara vez es el cuello de botella. Es una buena lección: &lt;strong&gt;cambiar de lenguaje ayuda poco si no atacas el cuello de botella&lt;/strong&gt;. Lo mismo vimos al &lt;a href=&quot;https://codigum.com/notas/microservicio-en-rust-rendimiento/&quot;&gt;medir nuestro microservicio&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;linux&quot;&gt;Linux 7.0: Rust deja de ser un experimento&lt;/h2&gt;
&lt;p&gt;En diciembre de 2025, la cumbre de mantenedores del kernel dio por concluido el experimento con Rust, y &lt;a rel=&quot;external&quot; href=&quot;https://www.heise.de/en/news/Linux-7-0-released-more-than-just-a-version-number-jump-11255754.html&quot;&gt;Linux 7.0&lt;/a&gt; lo hizo oficial al retirar esa etiqueta.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;El matiz:&lt;/strong&gt; Rust sigue siendo opcional, se usa sobre todo en controladores nuevos, y muchos subsistemas aún ofrecen poca o ninguna interfaz. El kernel no se está reescribiendo.&lt;/p&gt;
&lt;h2 id=&quot;pixel&quot;&gt;Pixel 10: Rust en el módem&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://blog.google/security/bringing-rust-to-the-pixel-baseband/&quot;&gt;Google&lt;/a&gt; integró un analizador de DNS en Rust en el firmware del módem del Pixel 10, el primer Pixel con un lenguaje seguro en memoria en ese componente.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Por qué importa:&lt;/strong&gt; el módem procesa datos no confiables que llegan por la red, y es una superficie de ataque remota. Es otro ejemplo del patrón más rentable: no reescribir todo, sino proteger el componente que recibe datos peligrosos.&lt;/p&gt;
&lt;h2 id=&quot;astral&quot;&gt;Astral y OpenAI&lt;/h2&gt;
&lt;p&gt;En marzo de 2026, &lt;a rel=&quot;external&quot; href=&quot;https://astral.sh/blog/openai&quot;&gt;Astral&lt;/a&gt;, creadora de &lt;code&gt;uv&lt;/code&gt; y Ruff, acordó unirse al equipo de Codex de OpenAI, y se comprometió a mantener sus herramientas abiertas. No encontramos confirmación del cierre de la operación, de modo que la presentamos como un acuerdo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Por qué importa:&lt;/strong&gt; en pocos meses, dos empresas de IA se han acercado a herramientas de desarrollo hechas en Rust: Anthropic compró Bun, y OpenAI acordó sumar a Astral.&lt;/p&gt;
&lt;h2 id=&quot;whatsapp&quot;&gt;WhatsApp: la mayor distribución de Rust&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://engineering.fb.com/2026/01/27/security/rust-at-scale-security-whatsapp/&quot;&gt;Meta&lt;/a&gt; reemplazó 160 000 líneas de C++ por 90 000 de Rust en &lt;code&gt;wamedia&lt;/code&gt;, la biblioteca que revisa archivos multimedia. Llega cada mes a miles de millones de dispositivos, y Meta la considera el mayor despliegue global de una biblioteca en Rust.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Por qué importa:&lt;/strong&gt; ese código procesa automáticamente archivos no confiables, justo donde un fallo de memoria es más peligroso.&lt;/p&gt;
&lt;h2 id=&quot;chrome&quot;&gt;Chrome retira FreeType&lt;/h2&gt;
&lt;p&gt;Chrome reemplazó FreeType con &lt;a rel=&quot;external&quot; href=&quot;https://developer.chrome.com/blog/memory-safety-fonts&quot;&gt;Skrifa, escrita en Rust&lt;/a&gt;, para procesar fuentes, y en Chrome 145 lo retiró de Blink. Google reporta 39 errores encontrados al probar el código nuevo, ninguno crítico para la seguridad.&lt;/p&gt;
&lt;h2 id=&quot;android&quot;&gt;Android baja del 20 %&lt;/h2&gt;
&lt;p&gt;En noviembre de 2025, &lt;a rel=&quot;external&quot; href=&quot;https://blog.google/security/rust-in-android-move-fast-fix-things/&quot;&gt;Google informó&lt;/a&gt; que los fallos de memoria bajaron del 20 % de las vulnerabilidades de Android por primera vez. Lo explicamos en &lt;a href=&quot;https://codigum.com/notas/que-es-seguridad-de-memoria/&quot;&gt;El 70 %&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;next&quot;&gt;Next.js adopta Turbopack&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://nextjs.org/blog/next-16&quot;&gt;Next.js 16&lt;/a&gt; convirtió a Turbopack, escrito en Rust, en su empaquetador por defecto en octubre de 2025. Vercel habla de compilaciones de producción de 2 a 5 veces más rápidas, según sus propias pruebas.&lt;/p&gt;
&lt;h2 id=&quot;apt&quot;&gt;APT dependerá de Rust&lt;/h2&gt;
&lt;p&gt;A fines de 2025, &lt;a rel=&quot;external&quot; href=&quot;https://heise.de/-10978235&quot;&gt;un mantenedor de APT anunció&lt;/a&gt; que el gestor de paquetes de Debian tendría dependencias obligatorias de Rust, no antes de mayo de 2026, para procesar con más seguridad formatos como &lt;code&gt;.deb&lt;/code&gt; y &lt;code&gt;.tar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;El matiz:&lt;/strong&gt; fue el anuncio de un mantenedor, no una declaración oficial de Debian, y generó críticas. No confirmamos en qué estado está hoy.&lt;/p&gt;
&lt;h2 id=&quot;cloudflare&quot;&gt;Cloudflare: FL2, y un tropiezo&lt;/h2&gt;
&lt;p&gt;En septiembre de 2025, &lt;a rel=&quot;external&quot; href=&quot;https://blog.cloudflare.com/20-percent-internet-upgrade/&quot;&gt;Cloudflare&lt;/a&gt; contó la reescritura en Rust de su sistema central. Reportó respuestas 10 ms más rápidas en la mediana y menos de la mitad de CPU que el sistema anterior.&lt;/p&gt;
&lt;p&gt;Dos meses después, &lt;a rel=&quot;external&quot; href=&quot;https://blog.cloudflare.com/18-november-2025-outage&quot;&gt;una caída del 18 de noviembre&lt;/a&gt; se originó en un pánico en ese mismo código, por un &lt;code&gt;unwrap()&lt;/code&gt;. Rust evita fallos de memoria, no errores de lógica ni malas decisiones de operación.&lt;/p&gt;
&lt;h2 id=&quot;que-tienen-en-comun&quot;&gt;Qué tienen en común&lt;/h2&gt;
&lt;p&gt;Mirando el conjunto, hay cuatro patrones:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Se empieza por lo expuesto:&lt;/strong&gt; parsers, módems y archivos no confiables. Lo vimos en &lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#whatsapp&quot;&gt;WhatsApp&lt;/a&gt;, el &lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#pixel&quot;&gt;Pixel&lt;/a&gt; y &lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#chrome&quot;&gt;Chrome&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Casi nadie reescribe todo.&lt;/strong&gt; Linux, Git, Astro y Bun conservan otros lenguajes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;El motivo principal suele ser la seguridad o el mantenimiento,&lt;/strong&gt; más que la velocidad.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;La IA abarata las migraciones,&lt;/strong&gt; pero no reemplaza las pruebas ni el criterio.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hay también una lectura menos entusiasta: que otros adopten Rust no significa que a ti te convenga. &lt;a href=&quot;https://codigum.com/por-que-rust/quien-usa-rust/&quot;&gt;Apple&lt;/a&gt;, por ejemplo, persigue la seguridad de memoria con Swift. Cada caso resolvía un problema concreto. Antes de seguirlos, responde las &lt;a href=&quot;https://codigum.com/notas/vale-la-pena-migrar-a-rust/&quot;&gt;cinco preguntas antes de migrar&lt;/a&gt;, y revisa &lt;a href=&quot;https://codigum.com/por-que-rust/quien-usa-rust/&quot;&gt;quién usa Rust&lt;/a&gt; para encontrar casos parecidos al tuyo.&lt;/p&gt;
&lt;p&gt;Actualizaremos esta nota cuando haya novedades importantes.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Recolector de basura vs. Rust: pausas, picos y latencia</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/recolector-de-basura-vs-rust/"/>
        <id>https://codigum.com/notas/recolector-de-basura-vs-rust/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/recolector-de-basura-vs-rust/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;Un recolector de basura te libera de pensar en la memoria, a cambio de CPU, memoria extra y momentos en que el sistema atiende a otra cosa.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Todo programa debe devolver la memoria que ya no usa. La pregunta no es si cuesta, sino &lt;strong&gt;quién paga, cuánto y en qué momento&lt;/strong&gt;. Esa respuesta define cómo se comporta tu sistema bajo carga.&lt;/p&gt;
&lt;p&gt;Esta nota no busca declarar un ganador. Para muchísimos sistemas, un recolector moderno es la decisión correcta. Pero si tu negocio depende de responder siempre a tiempo, conviene entender dónde nacen los picos.&lt;/p&gt;
&lt;h2 id=&quot;tres-formas-de-devolver-la-memoria&quot;&gt;Tres formas de devolver la memoria&lt;/h2&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 234&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Tres filas con la vida de un valor. En C lo libera quien programa. Con recolector, queda en espera hasta que el recolector pasa. En Rust se libera al terminar el bloque.&quot;&gt;&lt;defs&gt;&lt;pattern id=&quot;rayado&quot; width=&quot;7&quot; height=&quot;7&quot; patternUnits=&quot;userSpaceOnUse&quot; patternTransform=&quot;rotate(45)&quot;&gt;&lt;line class=&quot;dg__hatch&quot; x1=&quot;0&quot; y1=&quot;0&quot; x2=&quot;0&quot; y2=&quot;7&quot;/&gt;&lt;/pattern&gt;&lt;/defs&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;41&quot;&gt;C&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;112&quot; y=&quot;20&quot; width=&quot;188&quot; height=&quot;30&quot; rx=&quot;6&quot;/&gt;&lt;text class=&quot;dg__t dg__mid dg__on&quot; x=&quot;206&quot; y=&quot;40.5&quot;&gt;en uso&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;107&quot;&gt;Recolector&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;112&quot; y=&quot;86&quot; width=&quot;188&quot; height=&quot;30&quot; rx=&quot;6&quot;/&gt;&lt;text class=&quot;dg__t dg__mid dg__on&quot; x=&quot;206&quot; y=&quot;106.5&quot;&gt;en uso&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;173&quot;&gt;Rust&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;112&quot; y=&quot;152&quot; width=&quot;188&quot; height=&quot;30&quot; rx=&quot;6&quot;/&gt;&lt;text class=&quot;dg__t dg__mid dg__on&quot; x=&quot;206&quot; y=&quot;172.5&quot;&gt;en uso&lt;/text&gt;&lt;path class=&quot;dg__mark&quot; d=&quot;M302 14V56&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;310&quot; y=&quot;41&quot;&gt;free(): depende de ti&lt;/text&gt;&lt;rect fill=&quot;url(#rayado)&quot; class=&quot;dg__hbox&quot; x=&quot;302&quot; y=&quot;86&quot; width=&quot;138&quot; height=&quot;30&quot; rx=&quot;6&quot;/&gt;&lt;path class=&quot;dg__mark&quot; d=&quot;M440 80V122&quot;/&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;372&quot; y=&quot;106&quot;&gt;en espera&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;447&quot; y=&quot;106&quot;&gt;libera&lt;/text&gt;&lt;path class=&quot;dg__mark&quot; d=&quot;M302 146V188&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;310&quot; y=&quot;173&quot;&gt;} libera aquí, siempre&lt;/text&gt;&lt;path class=&quot;dg__axisl&quot; d=&quot;M112 208H476m-7-5 7 5-7 5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;112&quot; y=&quot;226&quot;&gt;tiempo&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Las tres liberan memoria. Cambia quién decide y cuándo ocurre.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Manual, como en C:&lt;/strong&gt; tú decides cuándo liberar. Es rápido y predecible, pero un error produce &lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/&quot;&gt;estos fallos&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Recolector de basura, como en Java, Go o C#:&lt;/strong&gt; un proceso busca lo que ya no se usa y lo recupera más tarde. Es seguro y cómodo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Propiedad, como en Rust:&lt;/strong&gt; el compilador decide dónde liberar, y lo escribe en el programa. &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html&quot;&gt;El Libro de Rust&lt;/a&gt; lo resume así: al salir de alcance, el valor se libera.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;como-trabaja-un-recolector-de-basura&quot;&gt;Cómo trabaja un recolector de basura&lt;/h2&gt;
&lt;p&gt;La idea central es la alcanzabilidad: si ningún camino lleva a un objeto, nadie podrá volver a usarlo.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 204&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Desde las raíces se llega a los objetos A, B y C, que se conservan. A los objetos D y E no se llega por ningún camino, así que son basura.&quot;&gt;&lt;rect class=&quot;dg__cellb&quot; x=&quot;0&quot; y=&quot;76&quot; width=&quot;88&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;44&quot; y=&quot;105.5&quot;&gt;Raíces&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M90 100H132m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;136&quot; y=&quot;76&quot; width=&quot;84&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;178&quot; y=&quot;105.5&quot;&gt;A&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M222 100H246V40H270m-7-5 7 5-7 5M246 100H270m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;274&quot; y=&quot;16&quot; width=&quot;84&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;316&quot; y=&quot;45.5&quot;&gt;B&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;274&quot; y=&quot;76&quot; width=&quot;84&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;316&quot; y=&quot;105.5&quot;&gt;C&lt;/text&gt;&lt;rect class=&quot;dg__free&quot; x=&quot;274&quot; y=&quot;146&quot; width=&quot;84&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__mm&quot; x=&quot;316&quot; y=&quot;175.5&quot;&gt;D&lt;/text&gt;&lt;rect class=&quot;dg__free&quot; x=&quot;392&quot; y=&quot;146&quot; width=&quot;84&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__mm&quot; x=&quot;434&quot; y=&quot;175.5&quot;&gt;E&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--off&quot; d=&quot;M360 170H390m-7-5 7 5-7 5&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;0&quot; y=&quot;160&quot;&gt;Alcanzables:&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;0&quot; y=&quot;180&quot;&gt;se conservan&lt;/text&gt;&lt;text class=&quot;dg__t dg__tbad&quot; x=&quot;476&quot; y=&quot;134&quot; text-anchor=&quot;end&quot;&gt;Sin camino: basura&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Marcar: recorrer todo lo que se alcanza desde las raíces. Barrer: recuperar el resto.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Los recolectores actuales son mucho más sofisticados que este esquema. Trabajan en paralelo a tu programa, dividen los objetos por edad y compactan la memoria. &lt;a rel=&quot;external&quot; href=&quot;https://docs.python.org/3/library/gc.html&quot;&gt;Python&lt;/a&gt; combina otra técnica, el conteo de referencias, con un recolector para los ciclos.&lt;/p&gt;
&lt;h2 id=&quot;el-costo-no-es-solo-la-pausa&quot;&gt;El costo no es solo la pausa&lt;/h2&gt;
&lt;p&gt;Se suele hablar de las pausas, pero son solo uno de tres costos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Memoria.&lt;/strong&gt; El recolector necesita espacio para trabajar. En Go, &lt;a rel=&quot;external&quot; href=&quot;https://tip.golang.org/doc/gc-guide&quot;&gt;duplicar &lt;code&gt;GOGC&lt;/code&gt; duplica la memoria adicional y reduce a la mitad el costo de CPU&lt;/a&gt;: es un intercambio explícito. Con el valor habitual de 100, el montón puede crecer hasta cerca del doble de los datos vivos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU.&lt;/strong&gt; Marcar objetos es trabajo real. La misma guía de Go indica que el recolector usa el 25 % de los recursos de CPU durante la fase de marcado.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Variación.&lt;/strong&gt; El trabajo llega en momentos que tu código no eligió, y compite con las peticiones en curso.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 232&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Dos gráficos con la misma escala. Con recolector, la memoria sube en dientes de sierra hasta cerca del doble de los datos vivos y baja en cada recolección. Con Rust, sigue de cerca a los datos vivos.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;14&quot;&gt;Con recolector de basura&lt;/text&gt;&lt;path class=&quot;dg__axisl&quot; d=&quot;M0 100H480&quot;/&gt;&lt;path class=&quot;dg__gc&quot; d=&quot;M0 64.1L4 62.6L8 61.0L12 59.4L16 57.9L20 56.3L24 54.7L28 53.2L32 51.6L36 50.1L40 48.6L44 47.2L48 45.8L52 44.4L56 43.1L60 41.8L64 40.6L68 39.4L72 38.3L76 37.3L80 36.3L84 35.4L88 34.5L92 33.7L96 32.9L100 32.1L104 31.4L108 30.7L112 64.6L116 63.7L120 62.7L124 61.8L128 60.8L132 59.8L136 58.9L140 57.9L144 56.8L148 55.8L152 54.7L156 53.5L160 52.4L164 51.1L168 49.8L172 48.5L176 47.1L180 45.7L184 44.2L188 42.6L192 41.0L196 39.3L200 37.6L204 35.9L208 34.2L212 32.4L216 30.6L220 28.8L224 63.1L228 61.6L232 60.0L236 58.5L240 57.0L244 55.5L248 54.0L252 52.5L256 51.1L260 49.7L264 48.4L268 47.1L272 45.9L276 44.7L280 43.6L284 42.5L288 41.4L292 40.5L296 39.5L300 38.7L304 37.8L308 37.0L312 36.2L316 35.5L320 34.7L324 34.0L328 33.3L332 32.5L336 65.5L340 64.6L344 63.6L348 62.5L352 61.5L356 60.5L360 59.4L364 58.2L368 57.1L372 55.9L376 54.6L380 53.3L384 51.9L388 50.5L392 49.1L396 47.5L400 46.0L404 44.4L408 42.7L412 41.1L416 39.3L420 37.6L424 35.9L428 34.1L432 32.3L436 30.6L440 28.8L444 27.1L448 62.3L452 60.8L456 59.4L460 57.9L464 56.5L468 55.1L472 53.8L476 52.4L480 51.2&quot;/&gt;&lt;path class=&quot;dg__live&quot; d=&quot;M0 64.1L4 63.8L8 63.6L12 63.3L16 63.0L20 62.8L24 62.6L28 62.4L32 62.2L36 62.1L40 61.9L44 61.9L48 61.8L52 61.8L56 61.8L60 61.8L64 61.9L68 62.0L72 62.2L76 62.3L80 62.5L84 62.8L88 63.0L92 63.2L96 63.5L100 63.8L104 64.1L108 64.3L112 64.6L116 64.9L120 65.2L124 65.4L128 65.6L132 65.8L136 66.0L140 66.2L144 66.3L148 66.4L152 66.4L156 66.5L160 66.5L164 66.4L168 66.3L172 66.2L176 66.1L180 65.9L184 65.7L188 65.5L192 65.3L196 65.0L200 64.8L204 64.5L208 64.2L212 63.9L216 63.7L220 63.4L224 63.1L228 62.9L232 62.7L236 62.4L240 62.3L244 62.1L248 62.0L252 61.9L256 61.8L260 61.8L264 61.8L268 61.8L272 61.9L276 62.0L280 62.1L284 62.3L288 62.5L292 62.7L296 62.9L300 63.2L304 63.4L308 63.7L312 64.0L316 64.2L320 64.5L324 64.8L328 65.1L332 65.3L336 65.5L340 65.8L344 65.9L348 66.1L352 66.2L356 66.3L360 66.4L364 66.5L368 66.5L372 66.4L376 66.4L380 66.3L384 66.1L388 66.0L392 65.8L396 65.6L400 65.4L404 65.1L408 64.9L412 64.6L416 64.3L420 64.0L424 63.8L428 63.5L432 63.2L436 63.0L440 62.7L444 62.5L448 62.3L452 62.2L456 62.0L460 61.9L464 61.8L468 61.8L472 61.8L476 61.8L480 61.9&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;480&quot; y=&quot;14&quot; text-anchor=&quot;end&quot;&gt;datos vivos: línea punteada&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;140&quot;&gt;Con Rust&lt;/text&gt;&lt;path class=&quot;dg__axisl&quot; d=&quot;M0 226H480&quot;/&gt;&lt;path class=&quot;dg__rs&quot; d=&quot;M0 187.4L4 187.1L8 186.8L12 186.6L16 186.3L20 186.1L24 185.8L28 185.6L32 185.5L36 185.3L40 185.2L44 185.1L48 185.1L52 185.1L56 185.1L60 185.1L64 185.2L68 185.3L72 185.4L76 185.6L80 185.8L84 186.0L88 186.3L92 186.5L96 186.8L100 187.1L104 187.3L108 187.6L112 187.9L116 188.2L120 188.4L124 188.7L128 188.9L132 189.1L136 189.3L140 189.4L144 189.6L148 189.6L152 189.7L156 189.7L160 189.7L164 189.7L168 189.6L172 189.5L176 189.4L180 189.2L184 189.0L188 188.8L192 188.6L196 188.3L200 188.0L204 187.8L208 187.5L212 187.2L216 186.9L220 186.7L224 186.4L228 186.2L232 185.9L236 185.7L240 185.5L244 185.4L248 185.2L252 185.2L256 185.1L260 185.1L264 185.1L268 185.1L272 185.2L276 185.3L280 185.4L284 185.6L288 185.7L292 185.9L296 186.2L300 186.4L304 186.7L308 187.0L312 187.2L316 187.5L320 187.8L324 188.1L328 188.3L332 188.6L336 188.8L340 189.0L344 189.2L348 189.4L352 189.5L356 189.6L360 189.7L364 189.7L368 189.7L372 189.7L376 189.6L380 189.5L384 189.4L388 189.3L392 189.1L396 188.9L400 188.6L404 188.4L408 188.1L412 187.9L416 187.6L420 187.3L424 187.0L428 186.8L432 186.5L436 186.2L440 186.0L444 185.8L448 185.6L452 185.4L456 185.3L460 185.2L464 185.1L468 185.1L472 185.1L476 185.1L480 185.1&quot;/&gt;&lt;path class=&quot;dg__live&quot; d=&quot;M0 190.1L4 189.8L8 189.6L12 189.3L16 189.0L20 188.8L24 188.6L28 188.4L32 188.2L36 188.1L40 187.9L44 187.9L48 187.8L52 187.8L56 187.8L60 187.8L64 187.9L68 188.0L72 188.2L76 188.3L80 188.5L84 188.8L88 189.0L92 189.2L96 189.5L100 189.8L104 190.1L108 190.3L112 190.6L116 190.9L120 191.2L124 191.4L128 191.6L132 191.8L136 192.0L140 192.2L144 192.3L148 192.4L152 192.4L156 192.5L160 192.5L164 192.4L168 192.3L172 192.2L176 192.1L180 191.9L184 191.7L188 191.5L192 191.3L196 191.0L200 190.8L204 190.5L208 190.2L212 189.9L216 189.7L220 189.4L224 189.1L228 188.9L232 188.7L236 188.4L240 188.3L244 188.1L248 188.0L252 187.9L256 187.8L260 187.8L264 187.8L268 187.8L272 187.9L276 188.0L280 188.1L284 188.3L288 188.5L292 188.7L296 188.9L300 189.2L304 189.4L308 189.7L312 190.0L316 190.2L320 190.5L324 190.8L328 191.1L332 191.3L336 191.5L340 191.8L344 191.9L348 192.1L352 192.2L356 192.3L360 192.4L364 192.5L368 192.5L372 192.4L376 192.4L380 192.3L384 192.1L388 192.0L392 191.8L396 191.6L400 191.4L404 191.1L408 190.9L412 190.6L416 190.3L420 190.0L424 189.8L428 189.5L432 189.2L436 189.0L440 188.7L444 188.5L448 188.3L452 188.2L456 188.0L460 187.9L464 187.8L468 187.8L472 187.8L476 187.8L480 187.9&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;480&quot; y=&quot;140&quot; text-anchor=&quot;end&quot;&gt;misma escala&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Un recolector necesita holgura para trabajar. Ilustración conceptual, no medición.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;por-que-aparecen-los-picos&quot;&gt;Por qué aparecen los picos&lt;/h2&gt;
&lt;p&gt;Go hace casi todo su trabajo de forma concurrente, y sus pausas completas son breves. Aun así, &lt;a rel=&quot;external&quot; href=&quot;https://tip.golang.org/doc/gc-guide&quot;&gt;su guía&lt;/a&gt; enumera varias fuentes de latencia: las pausas breves entre fases, los retrasos de planificación por el 25 % de CPU, las rutinas que deben ayudar al recolector cuando se asigna mucha memoria y el costo extra de escribir punteros durante el marcado.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 246&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Dos gráficos con la misma escala de tiempo de respuesta. Con recolector aparecen picos periódicos. Con Rust la línea se mantiene estable.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;14&quot;&gt;Con recolector de basura&lt;/text&gt;&lt;path class=&quot;dg__axisl&quot; d=&quot;M0 96H480&quot;/&gt;&lt;path class=&quot;dg__gc&quot; d=&quot;M0 85.2L3 86.3L6 83.2L9 86.7L12 83.9L15 84.9L18 86.8L21 84.1L24 87.0L27 84.5L30 86.8L33 86.6L36 84.6L39 82.1L42 86.4L45 85.8L48 83.3L51 81.3L54 83.6L57 84.7L60 81.2L63 36.5L66 49.1L69 64.0L72 72.4L75 77.4L78 79.4L81 78.3L84 83.6L87 82.0L90 83.3L93 84.9L96 83.8L99 86.8L102 86.8L105 85.9L108 83.0L111 84.6L114 85.3L117 83.6L120 84.4L123 85.3L126 82.3L129 82.9L132 85.7L135 83.6L138 84.0L141 81.8L144 82.7L147 85.4L150 81.1L153 86.5L156 84.6L159 82.5L162 86.3L165 84.2L168 86.9L171 83.1L174 82.5L177 83.7L180 81.8L183 85.3L186 82.9L189 83.5L192 83.6L195 84.4L198 82.0L201 81.4L204 84.3L207 32.7L210 54.0L213 61.5L216 69.3L219 72.0L222 76.2L225 81.6L228 82.3L231 81.4L234 87.1L237 84.3L240 86.2L243 86.5L246 86.8L249 82.5L252 86.4L255 85.7L258 84.8L261 81.8L264 86.7L267 84.4L270 83.8L273 81.7L276 82.1L279 81.9L282 85.5L285 84.6L288 85.0L291 81.7L294 81.3L297 86.3L300 86.1L303 85.8L306 85.8L309 84.2L312 83.6L315 85.6L318 87.2L321 84.6L324 84.9L327 83.7L330 81.3L333 82.9L336 84.0L339 83.4L342 83.0L345 86.9L348 81.6L351 32.0L354 49.0L357 60.9L360 70.8L363 75.7L366 80.6L369 79.4L372 84.3L375 85.1L378 85.9L381 86.2L384 85.1L387 86.9L390 87.2L393 86.3L396 86.6L399 84.9L402 87.0L405 81.8L408 83.4L411 86.3L414 85.6L417 85.0L420 84.9L423 86.4L426 82.0L429 81.1L432 84.3L435 84.2L438 86.7L441 86.6L444 85.1L447 85.6L450 82.1L453 86.2L456 87.0L459 81.3L462 83.9L465 86.3L468 40.1L471 58.6L474 65.4L477 69.1L480 74.0&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;480&quot; y=&quot;14&quot; text-anchor=&quot;end&quot;&gt;cada pico: el recolector compite&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;136&quot;&gt;Con Rust&lt;/text&gt;&lt;path class=&quot;dg__axisl&quot; d=&quot;M0 218H480&quot;/&gt;&lt;path class=&quot;dg__rs&quot; d=&quot;M0 207.2L3 208.3L6 205.2L9 208.7L12 205.9L15 206.9L18 208.8L21 206.1L24 209.0L27 206.5L30 208.8L33 208.6L36 206.6L39 204.1L42 208.4L45 207.8L48 205.3L51 203.3L54 205.6L57 206.7L60 203.2L63 208.9L66 203.9L69 207.4L72 208.3L75 208.5L78 207.3L81 204.2L84 208.1L87 205.6L90 205.3L93 206.9L96 205.8L99 208.8L102 208.8L105 207.9L108 205.0L111 206.6L114 207.3L117 205.6L120 206.4L123 207.3L126 204.3L129 204.9L132 207.7L135 205.6L138 206.0L141 203.8L144 204.7L147 207.4L150 203.1L153 208.5L156 206.6L159 204.5L162 208.3L165 206.2L168 208.9L171 205.1L174 204.5L177 205.7L180 203.8L183 207.3L186 204.9L189 205.5L192 205.6L195 206.4L198 204.0L201 203.4L204 206.3L207 205.1L210 208.8L213 204.9L216 205.2L219 203.1L222 204.1L225 207.4L228 206.8L231 205.1L234 209.1L237 206.3L240 208.2L243 208.5L246 208.8L249 204.5L252 208.4L255 207.7L258 206.8L261 203.8L264 208.7L267 206.4L270 205.8L273 203.7L276 204.1L279 203.9L282 207.5L285 206.6L288 207.0L291 203.7L294 203.3L297 208.3L300 208.1L303 207.8L306 207.8L309 206.2L312 205.6L315 207.6L318 209.2L321 206.6L324 206.9L327 205.7L330 203.3L333 204.9L336 206.0L339 205.4L342 205.0L345 208.9L348 203.6L351 204.4L354 203.8L357 204.3L360 206.8L363 206.7L366 208.6L369 205.3L372 208.8L375 208.8L378 207.9L381 208.2L384 207.1L387 208.9L390 209.2L393 208.3L396 208.6L399 206.9L402 209.0L405 203.8L408 205.4L411 208.3L414 207.6L417 207.0L420 206.9L423 208.4L426 204.0L429 203.1L432 206.3L435 206.2L438 208.7L441 208.6L444 207.1L447 207.6L450 204.1L453 208.2L456 209.0L459 203.3L462 205.9L465 208.3L468 205.8L471 209.0L474 205.9L477 203.2L480 203.9&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;480&quot; y=&quot;136&quot; text-anchor=&quot;end&quot;&gt;misma escala&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;0&quot; y=&quot;236&quot;&gt;tiempo de respuesta a lo largo del tiempo&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Ilustración conceptual, no medición. El tamaño de los picos depende del recolector, del montón y de la carga.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;El tiempo de un ciclo crece con los datos vivos y con la cantidad de punteros por recorrer. Por eso las cachés grandes en memoria son el caso difícil: cuanto más útil es la caché, más trabajo le das al recolector.&lt;/p&gt;
&lt;h2 id=&quot;que-le-pasa-al-flujo-del-sistema&quot;&gt;Qué le pasa al flujo del sistema&lt;/h2&gt;
&lt;p&gt;Aquí está lo que más se subestima: &lt;strong&gt;una pausa no solo retrasa a quien estaba siendo atendido&lt;/strong&gt;. Las peticiones siguen llegando, se acumulan y hay que atenderlas después, con la capacidad que sobra.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 194&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Durante una pausa de cincuenta milisegundos la cola crece. Después baja poco a poco y tarda ciento diecisiete milisegundos en vaciarse.&quot;&gt;&lt;rect class=&quot;dg__band&quot; x=&quot;76.3636&quot; y=&quot;30&quot; width=&quot;90.9091&quot; height=&quot;138&quot; rx=&quot;0&quot;/&gt;&lt;path class=&quot;dg__axisl&quot; d=&quot;M40 22V168H470&quot;/&gt;&lt;path class=&quot;dg__area&quot; d=&quot;M76.4 168L167.3 44L379.4 168Z&quot;/&gt;&lt;path class=&quot;dg__gc&quot; d=&quot;M40 168H76.4L167.3 44L379.4 168H470&quot;/&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;121.818&quot; y=&quot;24&quot;&gt;pausa: 50 ms&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;197.273&quot; y=&quot;48&quot;&gt;la cola tarda 117 ms en vaciarse&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;0&quot; y=&quot;34&quot;&gt;cola&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;470&quot; y=&quot;186&quot; text-anchor=&quot;end&quot;&gt;tiempo&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Con un 70 % de carga, una pausa de 50 ms afecta unos 167 ms de tráfico. La cola dura más que la pausa.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Cuanto más cargado está el sistema, menos capacidad libre tiene para recuperarse. La misma pausa duele mucho más al 90 % que al 50 %.&lt;/p&gt;
&lt;figure class=&quot;dg flujo&quot; data-flujo&gt;&lt;canvas class=&quot;flujo__c&quot; aria-hidden=&quot;true&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;flujo__ctl&quot;&gt;&lt;label&gt;&lt;span&gt;Pausa &lt;output data-v=&quot;pausa&quot;&gt;50 ms&lt;/output&gt;&lt;/span&gt;&lt;input type=&quot;range&quot; min=&quot;5&quot; max=&quot;300&quot; step=&quot;5&quot; value=&quot;50&quot; data-k=&quot;pausa&quot;&gt;&lt;/label&gt;&lt;label&gt;&lt;span&gt;Peticiones por segundo &lt;output data-v=&quot;rate&quot;&gt;1000&lt;/output&gt;&lt;/span&gt;&lt;input type=&quot;range&quot; min=&quot;100&quot; max=&quot;10000&quot; step=&quot;100&quot; value=&quot;1000&quot; data-k=&quot;rate&quot;&gt;&lt;/label&gt;&lt;label&gt;&lt;span&gt;Carga del servicio &lt;output data-v=&quot;carga&quot;&gt;70 %&lt;/output&gt;&lt;/span&gt;&lt;input type=&quot;range&quot; min=&quot;30&quot; max=&quot;95&quot; step=&quot;5&quot; value=&quot;70&quot; data-k=&quot;carga&quot;&gt;&lt;/label&gt;&lt;/div&gt;&lt;dl class=&quot;flujo__out&quot; aria-live=&quot;polite&quot;&gt;&lt;div&gt;&lt;dt&gt;Peticiones retenidas&lt;/dt&gt;&lt;dd data-o=&quot;ret&quot;&gt;50&lt;/dd&gt;&lt;/div&gt;&lt;div&gt;&lt;dt&gt;Tiempo en vaciar la cola&lt;/dt&gt;&lt;dd data-o=&quot;dren&quot;&gt;117 ms&lt;/dd&gt;&lt;/div&gt;&lt;div&gt;&lt;dt&gt;Peticiones afectadas&lt;/dt&gt;&lt;dd data-o=&quot;afe&quot;&gt;167&lt;/dd&gt;&lt;/div&gt;&lt;/dl&gt;&lt;figcaption&gt;Simulador con un modelo simplificado: cola = peticiones × pausa, y se vacía con la capacidad libre. La animación va en cámara lenta. Prueba subir la carga a 90 %.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;La regla es sencilla. Con una carga &lt;em&gt;u&lt;/em&gt;, la cola tarda en vaciarse la duración de la pausa multiplicada por &lt;em&gt;u&lt;/em&gt; / (1 − &lt;em&gt;u&lt;/em&gt;). Una pausa de 50 ms toma 50 ms más en vaciarse al 50 % de carga, y 450 ms al 90 %. Un sistema real es más complejo, pero la tendencia se mantiene.&lt;/p&gt;
&lt;h2 id=&quot;el-promedio-esconde-el-problema&quot;&gt;El promedio esconde el problema&lt;/h2&gt;
&lt;p&gt;Si mides solo el promedio, nunca verás esto. Por eso se usan percentiles: &lt;strong&gt;p99&lt;/strong&gt; es el tiempo por debajo del cual está el 99 % de las peticiones. Dicho de otro modo, 1 de cada 100 tarda más.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 186&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Un histograma de tiempos de respuesta. La mayoría de las peticiones son rápidas y se concentran a la izquierda, junto con la mediana y el promedio. A la derecha hay una cola de peticiones lentas, donde está el percentil 99.&quot;&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;1&quot; y=&quot;154&quot; width=&quot;12.1176&quot; height=&quot;2&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;15.1176&quot; y=&quot;150.702&quot; width=&quot;12.1176&quot; height=&quot;5.29774&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;29.2353&quot; y=&quot;118.662&quot; width=&quot;12.1176&quot; height=&quot;37.3377&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;43.3529&quot; y=&quot;72.9873&quot; width=&quot;12.1176&quot; height=&quot;83.0127&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;57.4706&quot; y=&quot;45.6694&quot; width=&quot;12.1176&quot; height=&quot;110.331&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;71.5882&quot; y=&quot;44&quot; width=&quot;12.1176&quot; height=&quot;112&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;85.7059&quot; y=&quot;58.6177&quot; width=&quot;12.1176&quot; height=&quot;97.3823&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;99.8235&quot; y=&quot;78.9455&quot; width=&quot;12.1176&quot; height=&quot;77.0545&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;113.941&quot; y=&quot;98.5489&quot; width=&quot;12.1176&quot; height=&quot;57.4511&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;128.059&quot; y=&quot;114.77&quot; width=&quot;12.1176&quot; height=&quot;41.2302&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;142.176&quot; y=&quot;127.13&quot; width=&quot;12.1176&quot; height=&quot;28.8699&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;156.294&quot; y=&quot;136.098&quot; width=&quot;12.1176&quot; height=&quot;19.9016&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;170.412&quot; y=&quot;142.411&quot; width=&quot;12.1176&quot; height=&quot;13.5891&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;184.529&quot; y=&quot;146.77&quot; width=&quot;12.1176&quot; height=&quot;9.22966&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;198.647&quot; y=&quot;149.746&quot; width=&quot;12.1176&quot; height=&quot;6.25412&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;212.765&quot; y=&quot;151.763&quot; width=&quot;12.1176&quot; height=&quot;4.23693&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;226.882&quot; y=&quot;153.126&quot; width=&quot;12.1176&quot; height=&quot;2.87408&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;241&quot; y=&quot;154&quot; width=&quot;12.1176&quot; height=&quot;2&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;255.118&quot; y=&quot;154&quot; width=&quot;12.1176&quot; height=&quot;2&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;269.235&quot; y=&quot;154&quot; width=&quot;12.1176&quot; height=&quot;2&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__fmut&quot; x=&quot;283.353&quot; y=&quot;154&quot; width=&quot;12.1176&quot; height=&quot;2&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;297.471&quot; y=&quot;154&quot; width=&quot;12.1176&quot; height=&quot;2&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;311.588&quot; y=&quot;149.618&quot; width=&quot;12.1176&quot; height=&quot;6.38223&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;325.706&quot; y=&quot;149.709&quot; width=&quot;12.1176&quot; height=&quot;6.29114&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;339.824&quot; y=&quot;149.772&quot; width=&quot;12.1176&quot; height=&quot;6.22835&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;353.941&quot; y=&quot;149.815&quot; width=&quot;12.1176&quot; height=&quot;6.18486&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;368.059&quot; y=&quot;153.494&quot; width=&quot;12.1176&quot; height=&quot;2.50562&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;382.176&quot; y=&quot;153.516&quot; width=&quot;12.1176&quot; height=&quot;2.48448&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;396.294&quot; y=&quot;153.53&quot; width=&quot;12.1176&quot; height=&quot;2.46964&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;410.412&quot; y=&quot;153.541&quot; width=&quot;12.1176&quot; height=&quot;2.45916&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;424.529&quot; y=&quot;154&quot; width=&quot;12.1176&quot; height=&quot;2&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;438.647&quot; y=&quot;154&quot; width=&quot;12.1176&quot; height=&quot;2&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;452.765&quot; y=&quot;154&quot; width=&quot;12.1176&quot; height=&quot;2&quot; rx=&quot;2&quot;/&gt;&lt;rect class=&quot;dg__frs&quot; x=&quot;466.882&quot; y=&quot;154&quot; width=&quot;12.1176&quot; height=&quot;2&quot; rx=&quot;2&quot;/&gt;&lt;path class=&quot;dg__axisl&quot; d=&quot;M0 156.5H480&quot;/&gt;&lt;path class=&quot;dg__mark&quot; d=&quot;M73.4 34V156&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;67.4118&quot; y=&quot;46&quot; text-anchor=&quot;end&quot;&gt;mediana&lt;/text&gt;&lt;path class=&quot;dg__mark&quot; d=&quot;M121.4 34V156&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;127.412&quot; y=&quot;46&quot;&gt;promedio&lt;/text&gt;&lt;path class=&quot;dg__mark&quot; d=&quot;M367.1 34V156&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;373.059&quot; y=&quot;46&quot;&gt;p99&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;0&quot; y=&quot;176&quot;&gt;rápido&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;480&quot; y=&quot;176&quot; text-anchor=&quot;end&quot;&gt;lento&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;420&quot; y=&quot;132&quot;&gt;la cola&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;La mediana y el promedio cuentan la historia de la mayoría. El p99 cuenta la de quien sufre. Ilustración conceptual.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Un p99 alto no es un detalle estadístico. En un servicio con un millón de peticiones al día, son diez mil respuestas lentas diarias, y suelen concentrarse en los momentos de mayor carga, cuando más importan.&lt;/p&gt;
&lt;h2 id=&quot;con-muchos-servicios-el-pico-deja-de-ser-raro&quot;&gt;Con muchos servicios, el pico deja de ser raro&lt;/h2&gt;
&lt;p&gt;Una acción de un usuario suele tocar varios servicios, y su respuesta es tan lenta como el más lento. Jeff Dean y Luiz Barroso lo describieron en &lt;a rel=&quot;external&quot; href=&quot;https://research.google/pubs/the-tail-at-scale/&quot;&gt;The Tail at Scale&lt;/a&gt;:&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 180&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Si cada servicio tarda de más en una de cada cien llamadas, una petición lenta afecta al 1 por ciento de usuarios con un servicio, 9,6 con diez, 22,2 con veinticinco, 39,5 con cincuenta y 63,4 con cien.&quot;&gt;&lt;text class=&quot;dg__t&quot; x=&quot;98&quot; y=&quot;26&quot; text-anchor=&quot;end&quot;&gt;1 servicio&lt;/text&gt;&lt;rect class=&quot;dg__fgc&quot; x=&quot;108&quot; y=&quot;8&quot; width=&quot;3.16&quot; height=&quot;26&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;119.16&quot; y=&quot;26&quot;&gt;1 %&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;98&quot; y=&quot;60&quot; text-anchor=&quot;end&quot;&gt;10 servicios&lt;/text&gt;&lt;rect class=&quot;dg__fgc&quot; x=&quot;108&quot; y=&quot;42&quot; width=&quot;30.2153&quot; height=&quot;26&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;146.215&quot; y=&quot;60&quot;&gt;9,6 %&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;98&quot; y=&quot;94&quot; text-anchor=&quot;end&quot;&gt;25 servicios&lt;/text&gt;&lt;rect class=&quot;dg__fgc&quot; x=&quot;108&quot; y=&quot;76&quot; width=&quot;70.2085&quot; height=&quot;26&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;186.208&quot; y=&quot;94&quot;&gt;22,2 %&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;98&quot; y=&quot;128&quot; text-anchor=&quot;end&quot;&gt;50 servicios&lt;/text&gt;&lt;rect class=&quot;dg__fgc&quot; x=&quot;108&quot; y=&quot;110&quot; width=&quot;124.818&quot; height=&quot;26&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;240.818&quot; y=&quot;128&quot;&gt;39,5 %&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;98&quot; y=&quot;162&quot; text-anchor=&quot;end&quot;&gt;100 servicios&lt;/text&gt;&lt;rect class=&quot;dg__fgc&quot; x=&quot;108&quot; y=&quot;144&quot; width=&quot;200.334&quot; height=&quot;26&quot; rx=&quot;4&quot;/&gt;&lt;text class=&quot;dg__t&quot; x=&quot;316.334&quot; y=&quot;162&quot;&gt;63,4 %&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Porcentaje de peticiones de usuario con al menos una respuesta lenta, si cada servicio se demora en 1 de cada 100 llamadas: 1 − 0,99&lt;sup&gt;n&lt;/sup&gt;. Es aritmética, no una medición.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Lo que en un servicio parecía raro, en un sistema de cien servicios le pasa a la mayoría de las peticiones.&lt;/p&gt;
&lt;h2 id=&quot;un-caso-real-discord&quot;&gt;Un caso real: Discord&lt;/h2&gt;
&lt;p&gt;El caso más citado es el de &lt;a rel=&quot;external&quot; href=&quot;https://discord.com/blog/why-discord-is-switching-from-go-to-rust&quot;&gt;Discord&lt;/a&gt;. Su servicio Read States, escrito en Go, guardaba decenas de millones de registros en una caché y mostraba picos periódicos de latencia. Discord los atribuyó al recolector: debía recorrer toda la caché, y Go &lt;a rel=&quot;external&quot; href=&quot;https://github.com/golang/go/blob/master/src/runtime/proc.go&quot;&gt;fuerza una recolección al menos cada dos minutos&lt;/a&gt;. Reducir la caché aliviaba los picos, pero empeoraba el p99, porque más consultas iban a la base de datos.&lt;/p&gt;
&lt;p&gt;Al reescribirlo en Rust, los picos desaparecieron. Con optimizaciones, superó a la versión anterior en latencia, CPU y memoria. Según &lt;a rel=&quot;external&quot; href=&quot;https://aws.amazon.com/blogs/opensource/sustainability-with-rust/&quot;&gt;un artículo de AWS&lt;/a&gt;, la versión en Rust fue más de 10 veces más rápida en general y redujo 100 veces las peores latencias.&lt;/p&gt;
&lt;p&gt;Conviene leerlo con cuidado:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Se trata de un servicio concreto, con un patrón muy favorable a Rust.&lt;/li&gt;
&lt;li&gt;Usaba Go 1.9, y el artículo es de 2020. Go ha seguido mejorando.&lt;/li&gt;
&lt;li&gt;Los propios autores aclaran que no recomiendan reescribirlo todo en Rust.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;otro-caso-apple-de-java-a-swift&quot;&gt;Otro caso: Apple, de Java a Swift&lt;/h2&gt;
&lt;p&gt;El problema no es exclusivo de Go, y la solución no siempre es Rust. En 2025, &lt;a rel=&quot;external&quot; href=&quot;https://www.swift.org/blog/swift-at-apple-migrating-the-password-monitoring-service-from-java/&quot;&gt;Apple contó&lt;/a&gt; que migró de Java a Swift el servicio que revisa contraseñas filtradas. Tras ajustar el recolector G1, seguía viendo pausas prolongadas bajo carga. Con Swift reportó cerca de un 40 % más de capacidad, memoria de cientos de megabytes por instancia, frente a decenas de gigabytes en Java, y latencias menores a 1 ms en el 99,9 % de las peticiones.&lt;/p&gt;
&lt;p&gt;Es un caso publicado por la empresa creadora de Swift, pero la lección es general: en servicios muy exigentes, una gestión de memoria determinista puede cambiar el resultado, sea con Rust o con otro lenguaje.&lt;/p&gt;
&lt;h2 id=&quot;como-libera-rust&quot;&gt;Cómo libera Rust&lt;/h2&gt;
&lt;p&gt;En Rust no hay un proceso aparte. El punto de liberación queda fijado al compilar:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    {
        let reporte = vec![0u8; 1024];
        println!(&amp;quot;{} bytes&amp;quot;, reporte.len());
    } // `reporte` se libera aquí, en este punto exacto

    println!(&amp;quot;La memoria ya se devolvió&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Por eso el costo es predecible: ocurre siempre en el mismo lugar del código, y lo paga la operación que creó el problema, no una petición ajena. Lo explicamos en la guía de &lt;a href=&quot;https://codigum.com/aprende/ownership/&quot;&gt;ownership&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;lo-medimos-nosotros&quot;&gt;Lo medimos nosotros&lt;/h2&gt;
&lt;p&gt;Quisimos comprobarlo. En &lt;a href=&quot;https://codigum.com/notas/microservicio-en-rust-rendimiento/&quot;&gt;nuestro microservicio de ejemplo&lt;/a&gt;, con 5 millones de registros en memoria y un solo núcleo, el p99 de Go subió a más de 80 ms. Con 4 núcleos bajó a 2,6 ms. Node.js, también con recolector, se mantuvo cerca de 2 ms con un núcleo. La conclusión es que no todos los recolectores se comportan igual, y que los recursos disponibles cambian el resultado.&lt;/p&gt;
&lt;h2 id=&quot;rust-tambien-puede-tener-picos&quot;&gt;Rust también puede tener picos&lt;/h2&gt;
&lt;p&gt;Sin recolector no hay magia. Estas son las fuentes habituales de picos en Rust:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Liberar estructuras enormes.&lt;/strong&gt; Soltar un mapa de un millón de entradas toma tiempo, y ocurre justo en esa línea.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bloquear el hilo en código asíncrono.&lt;/strong&gt; Una operación lenta dentro de una tarea detiene a las demás que comparten ese hilo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contención en candados.&lt;/strong&gt; Un &lt;code&gt;Mutex&lt;/code&gt; muy disputado produce colas, en cualquier lenguaje.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reservar memoria en la ruta crítica.&lt;/strong&gt; El asignador tampoco es gratis.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;El mundo exterior.&lt;/strong&gt; La red, el disco y la base de datos no saben en qué lenguaje escribes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La diferencia es que estos costos están a la vista, en tu código, y puedes moverlos de lugar:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::collections::HashMap;
use std::thread;

fn main() {
    let cache: HashMap&amp;lt;u64, String&amp;gt; =
        (0..1_000_000).map(|i| (i, i.to_string())).collect();

    // Liberar un millón de entradas toma tiempo.
    // Se entrega a otro hilo para no frenar la petición en curso.
    thread::spawn(move || drop(cache));

    println!(&amp;quot;La petición sigue su curso&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;los-recolectores-modernos-son-muy-buenos&quot;&gt;Los recolectores modernos son muy buenos&lt;/h2&gt;
&lt;p&gt;Sería deshonesto comparar Rust con los recolectores de hace quince años. &lt;a rel=&quot;external&quot; href=&quot;https://wiki.openjdk.org/display/zgc/Main&quot;&gt;ZGC, de Java&lt;/a&gt;, hace su trabajo costoso de forma concurrente, sin detener los hilos de la aplicación más de un milisegundo, con pausas independientes del tamaño del montón y para montones de hasta 16 TB.&lt;/p&gt;
&lt;p&gt;Eso cambia la discusión, pero no la elimina. Las pausas casi desaparecen, aunque el trabajo sigue existiendo: la misma documentación de ZGC advierte que demasiados hilos del recolector le quitan CPU a la aplicación, y recomienda que el sistema nunca supere el 70 % de uso de CPU.&lt;/p&gt;
&lt;h2 id=&quot;comparacion-directa&quot;&gt;Comparación directa&lt;/h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Aspecto&lt;/th&gt;&lt;th&gt;Recolector moderno&lt;/th&gt;&lt;th&gt;Rust&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Quién libera&lt;/td&gt;&lt;td&gt;Un proceso en tiempo de ejecución&lt;/td&gt;&lt;td&gt;El compilador lo fija en el código&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Cuándo&lt;/td&gt;&lt;td&gt;Cuando el recolector lo decide&lt;/td&gt;&lt;td&gt;Al salir de alcance&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Pausas&lt;/td&gt;&lt;td&gt;Desde breves hasta menos de 1 ms, según el recolector&lt;/td&gt;&lt;td&gt;Sin pausas de recolección&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;CPU&lt;/td&gt;&lt;td&gt;Trabajo adicional y continuo&lt;/td&gt;&lt;td&gt;Sin ese trabajo; el costo es la liberación puntual&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Memoria&lt;/td&gt;&lt;td&gt;Necesita holgura&lt;/td&gt;&lt;td&gt;Cerca de los datos vivos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Latencia de cola&lt;/td&gt;&lt;td&gt;Depende de la carga y de la configuración&lt;/td&gt;&lt;td&gt;Más predecible, sin estar garantizada&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Productividad inicial&lt;/td&gt;&lt;td&gt;Alta&lt;/td&gt;&lt;td&gt;Menor, con curva de aprendizaje real&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Contratación&lt;/td&gt;&lt;td&gt;Mercado amplio&lt;/td&gt;&lt;td&gt;Mercado más pequeño&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Ajuste&lt;/td&gt;&lt;td&gt;Parámetros del recolector&lt;/td&gt;&lt;td&gt;Diseño del código&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;cuando-el-recolector-es-la-mejor-opcion&quot;&gt;Cuándo el recolector es la mejor opción&lt;/h2&gt;
&lt;p&gt;Si tu duda concreta es entre dos lenguajes, mira &lt;a href=&quot;https://codigum.com/notas/rust-vs-go/&quot;&gt;Rust vs. Go&lt;/a&gt;. Quédate con tu recolector si:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tu sistema pasa la mayor parte del tiempo esperando a la base de datos o a la red.&lt;/li&gt;
&lt;li&gt;Tus objetivos de latencia se miden en cientos de milisegundos.&lt;/li&gt;
&lt;li&gt;Tu equipo domina el lenguaje, y el costo de infraestructura no es un problema.&lt;/li&gt;
&lt;li&gt;No has medido el problema. Sin datos, una migración es una apuesta.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rust empieza a tener sentido cuando el p99 o el p99.9 es un requisito del negocio, cuando manejas muchos datos en memoria o cuando el costo de CPU y memoria se nota en la factura. También &lt;a href=&quot;https://codigum.com/notas/huella-de-carbono-del-software/&quot;&gt;reduce la huella de carbono&lt;/a&gt;, en la medida en que reduce servidores.&lt;/p&gt;
&lt;h2 id=&quot;que-medir-antes-de-decidir&quot;&gt;Qué medir antes de decidir&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Los percentiles, no el promedio.&lt;/strong&gt; p50, p95, p99 y p99.9, por servicio y bajo carga real.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;El tiempo de recolección.&lt;/strong&gt; Actívalo con &lt;code&gt;GODEBUG=gctrace=1&lt;/code&gt; en Go o con &lt;code&gt;-Xlog:gc&lt;/code&gt; en Java.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Si los picos coinciden.&lt;/strong&gt; Compara los picos de latencia con los ciclos del recolector. Si no coinciden, el problema está en otra parte.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;La configuración.&lt;/strong&gt; Prueba primero a ajustar el recolector y a reducir asignaciones. Suele ser mucho más barato que migrar.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Un solo componente.&lt;/strong&gt; Si decides cambiar, elige el servicio más crítico y compara. Las &lt;a href=&quot;https://codigum.com/notas/vale-la-pena-migrar-a-rust/&quot;&gt;cinco preguntas antes de migrar&lt;/a&gt; ayudan a ordenar esa decisión.&lt;/li&gt;
&lt;/ol&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Rust vs. Go: cómo elegir sin fanatismos</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/rust-vs-go/"/>
        <id>https://codigum.com/notas/rust-vs-go/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/rust-vs-go/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;Go optimiza la simplicidad para el equipo. Rust optimiza las garantías y el control para el sistema.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Rust y Go se comparan todo el tiempo, y es normal: ambos son modernos, compilan a binarios nativos y se usan para servicios de red. Pero nacieron para resolver problemas distintos. Elegir bien depende menos del lenguaje que de tu problema.&lt;/p&gt;
&lt;h2 id=&quot;la-diferencia-de-fondo&quot;&gt;La diferencia de fondo&lt;/h2&gt;
&lt;p&gt;Go se diseñó para que equipos grandes escriban servicios concurrentes con poco esfuerzo: un lenguaje pequeño, compilación rápida y un recolector de basura que se encarga de la memoria.&lt;/p&gt;
&lt;p&gt;Rust se diseñó para dar el control de C++ con garantías de seguridad: sin recolector, con un compilador que comprueba mucho más antes de ejecutar. Esa exigencia es su costo, y también su beneficio.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 190&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Comparación: Go compila rápido, se aprende pronto, usa recolector y gorrutinas. Rust no tiene recolector, usa poca memoria, detecta más errores al compilar y llega a embebidos y navegador.&quot;&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;0&quot; y=&quot;0&quot; width=&quot;231&quot; height=&quot;190&quot; rx=&quot;12&quot;/&gt;&lt;text class=&quot;dg__h&quot; x=&quot;18&quot; y=&quot;32&quot;&gt;Go: simplicidad&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;18&quot; y=&quot;66&quot;&gt;Compila muy rápido&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;18&quot; y=&quot;96&quot;&gt;Se aprende en poco tiempo&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;18&quot; y=&quot;126&quot;&gt;Recolector de basura&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;18&quot; y=&quot;156&quot;&gt;Gorrutinas muy directas&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;249&quot; y=&quot;0&quot; width=&quot;231&quot; height=&quot;190&quot; rx=&quot;12&quot;/&gt;&lt;text class=&quot;dg__h&quot; x=&quot;267&quot; y=&quot;32&quot;&gt;Rust: garantías&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;267&quot; y=&quot;66&quot;&gt;Sin recolector de basura&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;267&quot; y=&quot;96&quot;&gt;Bajo uso de memoria&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;267&quot; y=&quot;126&quot;&gt;Más errores al compilar&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;267&quot; y=&quot;156&quot;&gt;Llega a embebidos y navegador&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;No es una competencia: cada uno optimiza algo distinto.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Aspecto&lt;/th&gt;&lt;th&gt;Go&lt;/th&gt;&lt;th&gt;Rust&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Memoria&lt;/td&gt;&lt;td&gt;Recolector de basura&lt;/td&gt;&lt;td&gt;Propiedad, sin recolector&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Seguridad de memoria&lt;/td&gt;&lt;td&gt;Sí&lt;/td&gt;&lt;td&gt;Sí, salvo en &lt;code&gt;unsafe&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Carreras de datos&lt;/td&gt;&lt;td&gt;Posibles; hay &lt;a rel=&quot;external&quot; href=&quot;https://go.dev/doc/articles/race_detector&quot;&gt;detector en ejecución&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/#carrera&quot;&gt;No compilan&lt;/a&gt; en Rust seguro&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Valores nulos&lt;/td&gt;&lt;td&gt;Existe &lt;code&gt;nil&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;Option&lt;/code&gt;, comprobado al compilar&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Errores&lt;/td&gt;&lt;td&gt;Valores que se revisan por convención&lt;/td&gt;&lt;td&gt;&lt;code&gt;Result&lt;/code&gt;, y el compilador avisa si lo ignoras&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Velocidad de compilación&lt;/td&gt;&lt;td&gt;Muy rápida&lt;/td&gt;&lt;td&gt;Más lenta&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Curva de aprendizaje&lt;/td&gt;&lt;td&gt;Días o semanas&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://codigum.com/notas/cuanto-tarda-un-equipo-en-aprender-rust/&quot;&gt;Semanas o meses&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Binario&lt;/td&gt;&lt;td&gt;Incluye el entorno de ejecución&lt;/td&gt;&lt;td&gt;Sin entorno de ejecución obligatorio&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Uso en embebidos&lt;/td&gt;&lt;td&gt;Limitado&lt;/td&gt;&lt;td&gt;Muy adecuado&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;rendimiento-lo-que-importa-de-verdad&quot;&gt;Rendimiento: lo que importa de verdad&lt;/h2&gt;
&lt;p&gt;En tareas limitadas por CPU, Rust suele sacar ventaja. Pero la diferencia que más se nota en producción no suele estar en el promedio, sino en la memoria y en la latencia de cola.&lt;/p&gt;
&lt;p&gt;La &lt;a rel=&quot;external&quot; href=&quot;https://tip.golang.org/doc/gc-guide&quot;&gt;guía oficial del recolector de Go&lt;/a&gt; es muy clara sobre esto: el recolector usa el 25 % de la CPU durante el marcado, y puede obligar a las rutinas a ayudarlo si se asigna mucha memoria. Si tu servicio guarda muchos datos en memoria, ese trabajo crece. Fue justo el &lt;a href=&quot;https://codigum.com/notas/recolector-de-basura-vs-rust/&quot;&gt;caso de Discord&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Para ver el orden de magnitud, en &lt;a href=&quot;https://codigum.com/notas/microservicio-en-rust-rendimiento/&quot;&gt;nuestro microservicio de ejemplo&lt;/a&gt; medimos Rust, Go, Node.js y Python con el mismo endpoint.&lt;/p&gt;
&lt;p&gt;Ahora bien, si tu servicio pasa casi todo el tiempo esperando a la base de datos, lo que ganes en el lenguaje apenas se notará. Mide antes. &lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#astro&quot;&gt;Astro lo mostró en 2026&lt;/a&gt;: al cambiar su compilador de Go a Rust ganó cerca de un 6 % en la compilación de su documentación, porque ese paso rara vez era el cuello de botella.&lt;/p&gt;
&lt;h2 id=&quot;concurrencia-dos-filosofias&quot;&gt;Concurrencia: dos filosofías&lt;/h2&gt;
&lt;p&gt;Go tiene una de sus mejores ideas en las gorrutinas: lanzar una tarea es tan simple como escribir &lt;code&gt;go&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;go&quot;&gt;go procesar(pedido) // simple y directo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rust usa &lt;code&gt;async&lt;/code&gt; y &lt;code&gt;await&lt;/code&gt;, normalmente con &lt;a rel=&quot;external&quot; href=&quot;https://tokio.rs&quot;&gt;Tokio&lt;/a&gt;. Es más explícito, tiene más conceptos y más detalles que aprender. Lo que recibes a cambio es que el compilador impide compartir datos de forma insegura entre hilos.&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use std::thread;

fn main() {
    let pedido = String::from(&amp;quot;A-100&amp;quot;);

    // `move` transfiere el dato al hilo: el compilador
    // no permite que el hilo original lo siga usando.
    let hilo = thread::spawn(move || println!(&amp;quot;Procesando {pedido}&amp;quot;));

    hilo.join().unwrap();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En Go, compartir un mapa entre gorrutinas sin protección compila sin aviso, y puede fallar en producción. Por eso existe &lt;code&gt;go test -race&lt;/code&gt;, que es muy útil, pero solo detecta las carreras que ocurren durante la prueba. En Rust, ese error no llega a compilar.&lt;/p&gt;
&lt;h2 id=&quot;productividad-menos-diferencia-de-la-que-se-cree&quot;&gt;Productividad: menos diferencia de la que se cree&lt;/h2&gt;
&lt;p&gt;Lo habitual es asumir que Go siempre será más productivo. Los datos disponibles son más matizados. En la conferencia Rust Nation 2024, Lars Bergstrom, de Google, &lt;a rel=&quot;external&quot; href=&quot;https://i-programmer.info/news/184-cc/17089-rust-twice-as-productive-as-c.html&quot;&gt;comentó&lt;/a&gt; que los equipos de Rust eran tan productivos como los de Go en reescrituras comparables, y el doble que los de C++.&lt;/p&gt;
&lt;p&gt;Conviene leer esto con prudencia: es una charla, no un estudio publicado, y Google no es una empresa promedio. Lo razonable es asumir que &lt;strong&gt;Go gana al inicio&lt;/strong&gt; y que la distancia se reduce cuando el equipo domina Rust. Compilar sigue siendo más lento: en la &lt;a rel=&quot;external&quot; href=&quot;https://opensource.googleblog.com/2023/06/rust-fact-vs-fiction-5-insights-from-googles-rust-journey-2022.html&quot;&gt;encuesta interna de Google&lt;/a&gt;, solo algo más del 40 % consideraba aceptable la velocidad del compilador.&lt;/p&gt;
&lt;h2 id=&quot;contratacion-y-ecosistema&quot;&gt;Contratación y ecosistema&lt;/h2&gt;
&lt;p&gt;Aquí Go suele llevar ventaja. Hay más perfiles disponibles, y cualquier persona con experiencia en backend aprende el lenguaje rápido. Su biblioteca estándar cubre muy bien HTTP y JSON, y buena parte de la infraestructura en la nube, como Kubernetes o Docker, está escrita en Go.&lt;/p&gt;
&lt;p&gt;Rust exige formar a tu equipo o competir por menos perfiles. En cambio, llega a lugares donde Go no entra con facilidad: &lt;a href=&quot;https://codigum.com/aprende/herramientas/&quot;&gt;embebidos, navegador, sistemas operativos y bibliotecas para otros lenguajes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;cuando-elegir-cada-uno&quot;&gt;Cuándo elegir cada uno&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Elige Go si:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tu prioridad es entregar servicios de red rápido, con un equipo que rota o crece.&lt;/li&gt;
&lt;li&gt;La lógica de negocio pesa más que el rendimiento.&lt;/li&gt;
&lt;li&gt;Tu latencia objetivo se mide en decenas de milisegundos o más, y no tienes grandes cachés en memoria.&lt;/li&gt;
&lt;li&gt;Trabajas en el ecosistema de Kubernetes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Elige Rust si:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El p99 o la memoria son requisitos del negocio.&lt;/li&gt;
&lt;li&gt;Haces trabajo intensivo de CPU: procesar datos, comprimir, analizar, cifrar.&lt;/li&gt;
&lt;li&gt;Procesas datos no confiables en la ruta crítica.&lt;/li&gt;
&lt;li&gt;Necesitas llegar a embebidos, WebAssembly o bibliotecas para Python o Node.js.&lt;/li&gt;
&lt;li&gt;Un fallo sale muy caro, y prefieres pagar esa seguridad en tiempo de desarrollo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;No tienes que elegir uno solo.&lt;/strong&gt; Muchas empresas combinan ambos: Go para la mayoría de servicios y Rust para los pocos componentes donde cada milisegundo o cada gigabyte cuenta.&lt;/p&gt;
&lt;h2 id=&quot;la-pregunta-correcta&quot;&gt;La pregunta correcta&lt;/h2&gt;
&lt;p&gt;No es &quot;¿cuál es mejor?&quot;, sino &quot;¿qué problema tengo, y cuánto me cuesta?&quot;. Si aún no lo sabes, mide primero.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Rust y código generado por IA: el compilador como revisor</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/rust-y-codigo-generado-por-ia/"/>
        <id>https://codigum.com/notas/rust-y-codigo-generado-por-ia/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/rust-y-codigo-generado-por-ia/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;Cuando una máquina escribe código más rápido de lo que podemos revisarlo, conviene un lenguaje en el que el compilador rechace parte de los errores.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Los asistentes de código cambiaron el problema. Antes costaba escribir software, y ahora cuesta más saber si lo escrito es correcto. Por eso la revisión pasó a ser el cuello de botella.&lt;/p&gt;
&lt;p&gt;Rust tiene aquí una propuesta interesante, y merece analizarse sin exagerar.&lt;/p&gt;
&lt;h2 id=&quot;lo-que-sabemos-sobre-el-codigo-generado&quot;&gt;Lo que sabemos sobre el código generado&lt;/h2&gt;
&lt;p&gt;Veracode &lt;a rel=&quot;external&quot; href=&quot;https://www.veracode.com/press-release/ai-generated-code-poses-major-security-risks-in-nearly-half-of-all-development-tasks-veracode-research-reveals/&quot;&gt;analizó en 2025&lt;/a&gt; 80 tareas de programación con más de 100 modelos. En el 45 % de los casos, el código introducía una vulnerabilidad. Java tuvo la peor tasa, con más del 70 %, y Python, C# y JavaScript quedaron entre el 38 % y el 45 %. Según la empresa, los resultados no mejoraban con los modelos nuevos.&lt;/p&gt;
&lt;p&gt;Dos advertencias: Veracode vende herramientas de seguridad, y sus pruebas se centraron en errores como inyección y cross-site scripting. Pero el mensaje general es razonable: &lt;strong&gt;el código generado se parece al que aprendió, incluidos sus errores&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;el-compilador-no-se-cansa&quot;&gt;El compilador no se cansa&lt;/h2&gt;
&lt;p&gt;Un revisor humano se fatiga. Revisa bien las primeras cien líneas y peor las mil siguientes. El compilador de Rust revisa siempre igual, y rechaza clases enteras de errores antes de llegar a una revisión:&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 128&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;El asistente genera código. El compilador lo rechaza con un error preciso y el asistente lo corrige. Luego Clippy y las pruebas filtran, y por último una persona decide.&quot;&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;0&quot; y=&quot;8&quot; width=&quot;100&quot; height=&quot;62&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;50&quot; y=&quot;34&quot;&gt;Asistente&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;50&quot; y=&quot;55&quot;&gt;genera&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M103 39H123.6m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;126.6&quot; y=&quot;8&quot; width=&quot;100&quot; height=&quot;62&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;176.6&quot; y=&quot;34&quot;&gt;Compilador&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;176.6&quot; y=&quot;55&quot;&gt;rechaza&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M229.6 39H250.2m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;253.2&quot; y=&quot;8&quot; width=&quot;100&quot; height=&quot;62&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;303.2&quot; y=&quot;34&quot;&gt;Clippy, pruebas&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;303.2&quot; y=&quot;55&quot;&gt;filtran&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M356.2 39H376.8m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;379.8&quot; y=&quot;8&quot; width=&quot;100&quot; height=&quot;62&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__c dg__cs dg__on&quot; x=&quot;429.8&quot; y=&quot;34&quot;&gt;Persona&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__on&quot; x=&quot;429.8&quot; y=&quot;55&quot;&gt;decide&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--bad&quot; d=&quot;M176 72V98H50V78m-5 7 5-7 5 7&quot;/&gt;&lt;text class=&quot;dg__t dg__mid dg__tbad&quot; x=&quot;113&quot; y=&quot;118&quot;&gt;error preciso: se corrige solo&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Cada etapa automática deja menos carga para la última, que sigue siendo humana.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Esto crea un ciclo útil con la IA. Si el asistente genera código con un problema de propiedad, el compilador lo rechaza con un mensaje preciso. El asistente lo lee y lo corrige. El ciclo ocurre antes de que una persona mire el código.&lt;/p&gt;
&lt;p&gt;Hay evidencia de que funciona, con matices. &lt;a rel=&quot;external&quot; href=&quot;https://www.microsoft.com/en-us/research/publication/fixing-rust-compilation-errors-using-llms/&quot;&gt;RustAssistant&lt;/a&gt;, un trabajo de Microsoft Research, conecta un modelo con el compilador y reporta cerca del 74 % de errores de compilación reales corregidos. Pero &lt;a rel=&quot;external&quot; href=&quot;https://arxiv.org/pdf/2505.10708&quot;&gt;otro trabajo sobre traducción de C a Rust&lt;/a&gt; advierte que los mensajes del compilador no bastan por sí solos: hacen falta instrucciones de reparación guiadas.&lt;/p&gt;
&lt;p&gt;El caso más llamativo es &lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#bun&quot;&gt;Bun&lt;/a&gt;, que en 2026 pasó de Zig a Rust con asistentes de IA, y con su suite de pruebas como red de seguridad. Lo presentó con una idea muy cercana a esta nota: los errores del compilador son mejor ciclo de retroalimentación que una guía de estilo. Aun así, reportó 19 regresiones.&lt;/p&gt;
&lt;p&gt;Y hay un riesgo sutil: corregir un error de compilación no significa que el programa haga lo correcto. A veces el fallo solo se traslada a una etapa posterior, y resulta más difícil de encontrar.&lt;/p&gt;
&lt;h2 id=&quot;lo-que-el-compilador-si-detecta&quot;&gt;Lo que el compilador sí detecta&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/&quot;&gt;Fallos de memoria&lt;/a&gt; en código seguro.&lt;/li&gt;
&lt;li&gt;Carreras de datos.&lt;/li&gt;
&lt;li&gt;Casos no tratados en un &lt;code&gt;match&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Valores opcionales usados sin comprobar.&lt;/li&gt;
&lt;li&gt;Errores ignorados, con una advertencia si no usas un &lt;code&gt;Result&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;lo-que-el-compilador-no-detecta&quot;&gt;Lo que el compilador no detecta&lt;/h2&gt;
&lt;p&gt;Aquí es donde se equivocan quienes prometen de más. Rust no sabe qué debería hacer tu programa, de modo que estos errores pasan sin aviso:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Autorización ausente:&lt;/strong&gt; una ruta que debería exigir permisos, y no lo hace.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lógica de negocio equivocada:&lt;/strong&gt; un descuento mal calculado compila perfectamente.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inyección SQL:&lt;/strong&gt; si concatenas texto, Rust no te salva. Usa consultas parametrizadas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secretos en el código:&lt;/strong&gt; una clave escrita en el repositorio compila sin problemas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependencias inventadas o maliciosas:&lt;/strong&gt; los asistentes pueden sugerir paquetes que no existen, y alguien podría registrarlos después.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;unsafe&lt;/code&gt; innecesario:&lt;/strong&gt; un modelo puede usarlo para &quot;resolver&quot; un error del compilador. Es la señal de alarma más clara.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;una-configuracion-sensata&quot;&gt;Una configuración sensata&lt;/h2&gt;
&lt;p&gt;Si tu equipo usa asistentes, esto cierra buena parte del riesgo. Lo primero es prohibir &lt;code&gt;unsafe&lt;/code&gt; en el código propio. Con esta línea, cualquier bloque &lt;code&gt;unsafe&lt;/code&gt; deja de compilar:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;#![forbid(unsafe_code)]

fn main() {
    println!(&amp;quot;Este proyecto no permite código unsafe&amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si de verdad necesitas &lt;code&gt;unsafe&lt;/code&gt;, aíslalo y &lt;a href=&quot;https://codigum.com/notas/unsafe-en-rust/&quot;&gt;audítalo&lt;/a&gt;. Lo segundo es endurecer el control de calidad en integración continua:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;bash&quot;&gt;cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo nextest run
cargo deny check
cargo audit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cada comando atiende un riesgo:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Comando&lt;/th&gt;&lt;th&gt;Qué revisa&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cargo fmt --check&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Formato uniforme, para que el diff sea legible&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cargo clippy&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://rust-lang.github.io/rust-clippy/&quot;&gt;Patrones incorrectos o sospechosos&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cargo nextest run&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Las pruebas&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cargo deny check&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/EmbarkStudios/cargo-deny&quot;&gt;Licencias y fuentes permitidas de dependencias&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cargo audit&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Vulnerabilidades conocidas en dependencias&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Encuéntralas todas en nuestra &lt;a href=&quot;https://codigum.com/aprende/herramientas/&quot;&gt;caja de herramientas&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;como-revisar-lo-que-escribe-un-asistente&quot;&gt;Cómo revisar lo que escribe un asistente&lt;/h2&gt;
&lt;p&gt;La revisión humana no desaparece, pero cambia de foco. Si el compilador ya cubrió la memoria, la persona puede concentrarse en lo importante:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;La intención:&lt;/strong&gt; ¿resuelve el problema correcto?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;La autorización:&lt;/strong&gt; ¿quién puede ejecutar esto?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Los límites:&lt;/strong&gt; ¿qué pasa con datos vacíos, enormes o maliciosos?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Las dependencias nuevas:&lt;/strong&gt; ¿existen, se mantienen, las necesitas?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Las pruebas:&lt;/strong&gt; ¿comprueban algo, o solo repiten la implementación?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cada &lt;code&gt;unsafe&lt;/code&gt;, &lt;code&gt;unwrap&lt;/code&gt; y &lt;code&gt;clone&lt;/code&gt;:&lt;/strong&gt; ¿tiene justificación?&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;entonces-rust-es-mejor-para-la-ia&quot;&gt;Entonces, ¿Rust es mejor para la IA?&lt;/h2&gt;
&lt;p&gt;Lo honesto es decir que no hay un estudio concluyente sobre si el Rust generado es más seguro en general. Lo que sí está claro es el mecanismo: &lt;strong&gt;más errores detectados por una máquina significa menos carga para quien revisa&lt;/strong&gt;. El costo es que el asistente tardará más ciclos en conseguir que compile, y que necesitas personas que entiendan lo que aprueban.&lt;/p&gt;
&lt;p&gt;La IA no elimina la necesidad de criterio, sino que la vuelve más valiosa.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Seguridad de software y regulación en Latinoamérica: qué exigen de verdad</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/seguridad-y-regulacion-en-latinoamerica/"/>
        <id>https://codigum.com/notas/seguridad-y-regulacion-en-latinoamerica/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/seguridad-y-regulacion-en-latinoamerica/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;Ninguna norma te exige un lenguaje. Todas te exigen demostrar que gestionas el riesgo de tu software.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Las regulaciones de ciberseguridad están llegando al código. Ya no alcanza con un firewall y una política en PDF: cada vez más, una auditoría pregunta cómo desarrollas, cómo pruebas y cómo tratas tus vulnerabilidades.&lt;/p&gt;
&lt;p&gt;Esta nota resume qué piden algunas normas relevantes para la región. Es una guía de ingeniería, no asesoría legal: cada norma tiene alcance, plazos y excepciones que debes validar con tus especialistas.&lt;/p&gt;
&lt;h2 id=&quot;primero-lo-que-no-dicen&quot;&gt;Primero, lo que no dicen&lt;/h2&gt;
&lt;p&gt;Ninguna de estas normas obliga a usar Rust ni un lenguaje seguro en memoria. Quien diga lo contrario te está vendiendo algo.&lt;/p&gt;
&lt;p&gt;En Estados Unidos, la &lt;a rel=&quot;external&quot; href=&quot;https://www.cisa.gov/news-events/alerts/2025/06/24/new-guidance-released-reducing-memory-related-vulnerabilities&quot;&gt;guía de NSA y CISA de 2025&lt;/a&gt; sí recomienda estos lenguajes como la mitigación más completa contra esa clase de fallos, pero es una recomendación, no una obligación.&lt;/p&gt;
&lt;p&gt;Lo que sí hacen las normas es exigir controles, pruebas y evidencia. Y ahí es donde tus decisiones técnicas pesan.&lt;/p&gt;
&lt;h2 id=&quot;comparacion-rapida&quot;&gt;Comparación rápida&lt;/h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Marco&lt;/th&gt;&lt;th&gt;A quién aplica&lt;/th&gt;&lt;th&gt;Foco en software&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;SBS 504-2021&lt;/strong&gt; (Perú)&lt;/td&gt;&lt;td&gt;Sector financiero supervisado&lt;/td&gt;&lt;td&gt;Desarrollo seguro, pruebas, API, terceros&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Ley 29733&lt;/strong&gt; (Perú)&lt;/td&gt;&lt;td&gt;Quien trata datos personales&lt;/td&gt;&lt;td&gt;Protección de datos, oficial de datos en ciertos casos&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Ley 21.663&lt;/strong&gt; (Chile)&lt;/td&gt;&lt;td&gt;Servicios esenciales y operadores de importancia vital&lt;/td&gt;&lt;td&gt;Sistemas de gestión, reporte de incidentes&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;BCB 538&lt;/strong&gt; (Brasil)&lt;/td&gt;&lt;td&gt;Instituciones reguladas por el Banco Central&lt;/td&gt;&lt;td&gt;Controles mínimos, pruebas de intrusión, Pix&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Ley de Ciberresiliencia&lt;/strong&gt; (UE)&lt;/td&gt;&lt;td&gt;Productos con elementos digitales en el mercado europeo&lt;/td&gt;&lt;td&gt;Seguridad en diseño, vulnerabilidades, reportes&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;peru-la-sbs-y-el-desarrollo-seguro&quot;&gt;Perú: la SBS y el desarrollo seguro&lt;/h2&gt;
&lt;p&gt;El &lt;a rel=&quot;external&quot; href=&quot;https://busquedas.elperuano.pe/dispositivo/NL/1929393-1&quot;&gt;Reglamento SBS 504-2021&lt;/a&gt; es, para el sector financiero, el documento clave. Su artículo 12 pide incluir prácticas de seguridad en la planificación, el desarrollo y la operación, e implementar procedimientos con prácticas de desarrollo seguro. Estos son los puntos más útiles para un equipo técnico:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Control de cambios:&lt;/strong&gt; limitar quién modifica el código fuente, con un estricto control (art. 12, num. 5, lit. c).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pruebas antes de producción:&lt;/strong&gt; técnicas, funcionales y de seguridad de la información (lit. e).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ambientes separados:&lt;/strong&gt; desarrollo, pruebas y producción (num. 3, lit. c).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API:&lt;/strong&gt; prácticas de desarrollo seguro, revisión de codificación segura, análisis de vulnerabilidades y pruebas de penetración (art. 21).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Terceros:&lt;/strong&gt; evaluar amenazas en lo que proveen, definir responsabilidades y, en la nube, verificar certificaciones (art. 22 a 24).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El reglamento no fija un estándar de código ni una herramienta específica. Te deja elegir, pero debes poder demostrar que lo haces. Además, tiene regímenes distintos según la entidad, y fue &lt;a rel=&quot;external&quot; href=&quot;https://busquedas.elperuano.pe/dispositivo/NL/1955432-1&quot;&gt;modificado por la Resolución 01515-2021&lt;/a&gt;, de modo que conviene revisar la versión vigente.&lt;/p&gt;
&lt;p&gt;Fuera del sistema financiero, el &lt;a rel=&quot;external&quot; href=&quot;https://insightplus.bakermckenzie.com/bm/data-technology/peru-new-regulations-of-the-personal-data-protection-law_1&quot;&gt;nuevo reglamento de la Ley 29733&lt;/a&gt;, en vigor desde 2025, refuerza las obligaciones sobre datos personales.&lt;/p&gt;
&lt;h2 id=&quot;chile-la-ley-marco-de-ciberseguridad&quot;&gt;Chile: la Ley Marco de Ciberseguridad&lt;/h2&gt;
&lt;p&gt;La &lt;a rel=&quot;external&quot; href=&quot;https://www.bcn.cl/leychile/navegar?idNorma=1202434&quot;&gt;Ley 21.663&lt;/a&gt; creó la Agencia Nacional de Ciberseguridad. Distingue deberes generales, como reportar incidentes, de deberes específicos para los Operadores de Importancia Vital, como implementar un sistema de gestión de seguridad de la información.&lt;/p&gt;
&lt;p&gt;La agencia ha &lt;a rel=&quot;external&quot; href=&quot;https://www.carey.cl/en/anci-publishes-second-preliminary-list-of-vital-importance-operators&quot;&gt;publicado nóminas de esos operadores&lt;/a&gt;, y las multas pueden llegar a 20 000 UTM, con hasta el doble para esos operadores. Si das servicios a uno de ellos, es probable que sus exigencias te lleguen por contrato.&lt;/p&gt;
&lt;h2 id=&quot;brasil-el-banco-central-tras-el-caso-c-m&quot;&gt;Brasil: el Banco Central tras el caso C&amp;amp;M&lt;/h2&gt;
&lt;p&gt;En 2025, un &lt;a rel=&quot;external&quot; href=&quot;https://finsidersbrasil.com.br/reportagem-exclusiva-fintechs/ataque-hacker-cm-software-1-ano-depois-o-que-mudou/&quot;&gt;ataque a C&amp;amp;M Software&lt;/a&gt;, proveedora conectada al sistema financiero, desvió al menos R$ 800 millones, según reportes de prensa. La lección fue incómoda: el eslabón débil era un tercero. En diciembre de ese año, el Banco Central publicó la &lt;a rel=&quot;external&quot; href=&quot;https://okai.com.br/documento/2025-12-18/resolucao-bcb-n-538&quot;&gt;Resolución BCB 538&lt;/a&gt;, que endurece los requisitos para las entidades reguladas. Según resúmenes jurídicos, incluye grupos de controles mínimos, pruebas de intrusión anuales y el aislamiento de los ambientes de Pix.&lt;/p&gt;
&lt;p&gt;Si desarrollas para banca o pagos, esto te incumbe aunque no estés en Brasil: es probable que marque tendencia en la región.&lt;/p&gt;
&lt;h2 id=&quot;europa-una-razon-para-exportadores&quot;&gt;Europa: una razón para exportadores&lt;/h2&gt;
&lt;p&gt;Si vendes software a Europa, presta atención a la Ley de Ciberresiliencia. Según &lt;a rel=&quot;external&quot; href=&quot;https://www.jonesday.com/en/insights/2026/07/eu-cyber-resilience-act-24hour-reporting-duties-start-september-11-2026&quot;&gt;Jones Day&lt;/a&gt;, desde el 11 de septiembre de 2026 los fabricantes deben reportar vulnerabilidades explotadas e incidentes graves, con una alerta en 24 horas. La mayoría de las demás obligaciones aplican desde el 11 de diciembre de 2027.&lt;/p&gt;
&lt;p&gt;Para una empresa latinoamericana que exporta software, esto dejó de ser un tema lejano.&lt;/p&gt;
&lt;h2 id=&quot;la-evidencia-que-si-puedes-preparar&quot;&gt;La evidencia que sí puedes preparar&lt;/h2&gt;
&lt;p&gt;Todas estas normas convergen en lo mismo. Aquí tienes una lista práctica, útil en cualquier jurisdicción:&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 172&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Seis tipos de evidencia: inventario de componentes, control de cambios, pruebas antes de producción, gestión de vulnerabilidades, control de terceros y reporte de incidentes.&quot;&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;0&quot; y=&quot;0&quot; width=&quot;152&quot; height=&quot;80&quot; rx=&quot;12&quot;/&gt;&lt;path class=&quot;dg__tick&quot; d=&quot;M16 26l4 4 8-9&quot;/&gt;&lt;text class=&quot;dg__h dg__cs&quot; x=&quot;36&quot; y=&quot;32&quot;&gt;Inventario&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;16&quot; y=&quot;60&quot;&gt;qué software usas&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;164&quot; y=&quot;0&quot; width=&quot;152&quot; height=&quot;80&quot; rx=&quot;12&quot;/&gt;&lt;path class=&quot;dg__tick&quot; d=&quot;M180 26l4 4 8-9&quot;/&gt;&lt;text class=&quot;dg__h dg__cs&quot; x=&quot;200&quot; y=&quot;32&quot;&gt;Cambios&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;180&quot; y=&quot;60&quot;&gt;quién modifica qué&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;328&quot; y=&quot;0&quot; width=&quot;152&quot; height=&quot;80&quot; rx=&quot;12&quot;/&gt;&lt;path class=&quot;dg__tick&quot; d=&quot;M344 26l4 4 8-9&quot;/&gt;&lt;text class=&quot;dg__h dg__cs&quot; x=&quot;364&quot; y=&quot;32&quot;&gt;Pruebas&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;344&quot; y=&quot;60&quot;&gt;antes de producción&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;0&quot; y=&quot;92&quot; width=&quot;152&quot; height=&quot;80&quot; rx=&quot;12&quot;/&gt;&lt;path class=&quot;dg__tick&quot; d=&quot;M16 118l4 4 8-9&quot;/&gt;&lt;text class=&quot;dg__h dg__cs&quot; x=&quot;36&quot; y=&quot;124&quot;&gt;Vulnerabilidades&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;16&quot; y=&quot;152&quot;&gt;detectar y priorizar&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;164&quot; y=&quot;92&quot; width=&quot;152&quot; height=&quot;80&quot; rx=&quot;12&quot;/&gt;&lt;path class=&quot;dg__tick&quot; d=&quot;M180 118l4 4 8-9&quot;/&gt;&lt;text class=&quot;dg__h dg__cs&quot; x=&quot;200&quot; y=&quot;124&quot;&gt;Terceros&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;180&quot; y=&quot;152&quot;&gt;contratos y controles&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;328&quot; y=&quot;92&quot; width=&quot;152&quot; height=&quot;80&quot; rx=&quot;12&quot;/&gt;&lt;path class=&quot;dg__tick&quot; d=&quot;M344 118l4 4 8-9&quot;/&gt;&lt;text class=&quot;dg__h dg__cs&quot; x=&quot;364&quot; y=&quot;124&quot;&gt;Incidentes&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;344&quot; y=&quot;152&quot;&gt;reportar a tiempo&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Seis cosas que una auditoría suele preguntar, escritas como evidencia que puedes preparar.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id=&quot;como-ayuda-rust&quot;&gt;Cómo ayuda Rust&lt;/h2&gt;
&lt;p&gt;Rust no te da cumplimiento, pero reduce trabajo y riesgo en varios puntos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Elimina una clase de vulnerabilidades&lt;/strong&gt; en el código seguro, antes de llegar a las pruebas. Vimos &lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/&quot;&gt;cuáles&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hace visible el riesgo:&lt;/strong&gt; el código &lt;code&gt;unsafe&lt;/code&gt; queda marcado y se puede &lt;a href=&quot;https://codigum.com/notas/unsafe-en-rust/&quot;&gt;auditar&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Facilita el control de dependencias:&lt;/strong&gt; con &lt;code&gt;Cargo.lock&lt;/code&gt;, &lt;code&gt;cargo audit&lt;/code&gt; y &lt;code&gt;cargo deny&lt;/code&gt; puedes bloquear versiones y documentar lo que usas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sigue siendo necesario todo lo demás: autorización, cifrado, gestión de secretos, registro, respuesta a incidentes. Y como vimos en &lt;a href=&quot;https://codigum.com/por-que-rust/&quot;&gt;Evidencia&lt;/a&gt;, cambiar de lenguaje no siempre es lo más urgente.&lt;/p&gt;
&lt;h2 id=&quot;por-donde-empezar&quot;&gt;Por dónde empezar&lt;/h2&gt;
&lt;p&gt;No empieces por reescribir nada. Empieza por saber dónde estás: qué sistemas son críticos, qué depende de terceros y qué evidencia te falta. Ese inventario suele ser más valioso que cualquier herramienta.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>unsafe en Rust: qué es, cuándo usarlo y cómo auditarlo</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/unsafe-en-rust/"/>
        <id>https://codigum.com/notas/unsafe-en-rust/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/unsafe-en-rust/">&lt;aside class=&quot;callout callout--frase&quot;&gt;
&lt;p class=&quot;callout__t&quot;&gt;En una frase&lt;/p&gt;
&lt;p&gt;&lt;code&gt;unsafe&lt;/code&gt; no significa inseguro: significa que aquí la responsabilidad pasa del compilador a ti.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Cuando alguien dice que Rust es seguro, la respuesta típica es: &quot;pero tiene &lt;code&gt;unsafe&lt;/code&gt;&quot;. Es cierto. Y entender qué significa es la diferencia entre confiar a ciegas y confiar con criterio.&lt;/p&gt;
&lt;h2 id=&quot;por-que-existe&quot;&gt;Por qué existe&lt;/h2&gt;
&lt;p&gt;El compilador de Rust es conservador. Rechaza todo lo que no puede demostrar que es correcto, incluso programas correctos. Y hay trabajo que por naturaleza no puede comprobar: hablar con el hardware, llamar a código en C o construir las propias estructuras de la biblioteca estándar.&lt;/p&gt;
&lt;p&gt;Sin &lt;code&gt;unsafe&lt;/code&gt;, Rust no podría hacer eso. &lt;code&gt;Vec&lt;/code&gt;, por ejemplo, gestiona memoria manualmente por dentro, y te ofrece por fuera una interfaz segura.&lt;/p&gt;
&lt;h2 id=&quot;que-permite-de-verdad&quot;&gt;Qué permite de verdad&lt;/h2&gt;
&lt;p&gt;Aquí está el malentendido más común. &lt;code&gt;unsafe&lt;/code&gt; &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/ch20-01-unsafe-rust.html&quot;&gt;no apaga el verificador de préstamos&lt;/a&gt; ni el resto de comprobaciones. Solo da acceso a cinco operaciones:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Desreferenciar un puntero crudo.&lt;/li&gt;
&lt;li&gt;Llamar a una función o método &lt;code&gt;unsafe&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Acceder a una variable estática mutable o modificarla.&lt;/li&gt;
&lt;li&gt;Implementar un &lt;em&gt;trait&lt;/em&gt; &lt;code&gt;unsafe&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Acceder a los campos de una &lt;code&gt;union&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Todo lo demás se sigue comprobando dentro del bloque. Y fuera de él, &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/nomicon/meet-safe-and-unsafe.html&quot;&gt;si solo escribes Rust seguro&lt;/a&gt;, no deberías encontrar comportamiento indefinido.&lt;/p&gt;
&lt;h2 id=&quot;la-idea-central-abstracciones-seguras&quot;&gt;La idea central: abstracciones seguras&lt;/h2&gt;
&lt;p&gt;La regla de oro es encerrar &lt;code&gt;unsafe&lt;/code&gt; en una función pequeña y exponer una interfaz segura. Quien la usa no puede provocar un error, y la responsabilidad queda en un solo lugar.&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 180&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Tu código llama a una interfaz segura. Por dentro, esta comprueba la condición y solo después entra en un pequeño bloque unsafe documentado.&quot;&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;0&quot; y=&quot;62&quot; width=&quot;96&quot; height=&quot;56&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__cs&quot; x=&quot;48&quot; y=&quot;95.5&quot;&gt;Tu código&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M98 90H136m-7-5 7 5-7 5&quot;/&gt;&lt;rect class=&quot;dg__cellb&quot; x=&quot;140&quot; y=&quot;4&quot; width=&quot;340&quot; height=&quot;172&quot; rx=&quot;14&quot;/&gt;&lt;text class=&quot;dg__h&quot; x=&quot;158&quot; y=&quot;30&quot;&gt;Interfaz segura: ultimo(&amp;amp;lista)&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;158&quot; y=&quot;56&quot;&gt;1. Comprueba que la lista no esté vacía&lt;/text&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;158&quot; y=&quot;74&quot; width=&quot;304&quot; height=&quot;84&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__h&quot; x=&quot;174&quot; y=&quot;100&quot;&gt;unsafe&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;174&quot; y=&quot;124&quot;&gt;2. Lee sin comprobar de nuevo&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;174&quot; y=&quot;144&quot;&gt;SAFETY: la condición ya se verificó&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Quien llama no puede provocar el error: el riesgo vive en un solo lugar, marcado y documentado.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Este ejemplo devuelve el último elemento de una lista. Comprueba la condición antes de entrar en la zona &lt;code&gt;unsafe&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;/// Devuelve el último elemento, si existe.
fn ultimo(lista: &amp;amp;[i32]) -&amp;gt; Option&amp;lt;i32&amp;gt; {
    if lista.is_empty() {
        return None;
    }

    // SAFETY: `lista` no está vacía, de modo que `len() - 1`
    // es un índice válido.
    Some(unsafe { *lista.get_unchecked(lista.len() - 1) })
}

fn main() {
    println!(&amp;quot;{:?}&amp;quot;, ultimo(&amp;amp;[1, 2, 3])); // Some(3)
    println!(&amp;quot;{:?}&amp;quot;, ultimo(&amp;amp;[]));        // None
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fíjate en el comentario &lt;code&gt;SAFETY&lt;/code&gt;. Explica por qué la operación es correcta. Es una convención muy extendida, y Clippy puede exigirla con &lt;a rel=&quot;external&quot; href=&quot;https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks&quot;&gt;&lt;code&gt;undocumented_unsafe_blocks&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Por cierto, en un caso real bastaría con &lt;code&gt;lista.last().copied()&lt;/code&gt;. Es un ejemplo para mostrar la forma, y demuestra lo primero que debes preguntarte: ¿de verdad lo necesitas?&lt;/p&gt;
&lt;h2 id=&quot;cuando-se-justifica&quot;&gt;Cuándo se justifica&lt;/h2&gt;
&lt;p&gt;Sí suele estar justificado en:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Interoperabilidad:&lt;/strong&gt; llamar a bibliotecas en C o C++, como vimos en la &lt;a href=&quot;https://codigum.com/notas/adoptar-rust-en-cpp/&quot;&gt;guía de adopción en C++&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hardware:&lt;/strong&gt; escribir registros en un microcontrolador o un driver.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Estructuras de datos a bajo nivel:&lt;/strong&gt; cuando la biblioteca estándar no cubre tu caso.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rendimiento comprobado:&lt;/strong&gt; solo si una medición muestra que importa.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No se justifica para:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Callar al compilador.&lt;/strong&gt; Si el verificador se queja, casi siempre tiene razón. Es el error típico de quien empieza, y de los &lt;a href=&quot;https://codigum.com/notas/rust-y-codigo-generado-por-ia/&quot;&gt;asistentes de IA&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimizar por intuición.&lt;/strong&gt; El compilador suele eliminar las comprobaciones de límites cuando puede demostrar que sobran.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evitar diseñar bien.&lt;/strong&gt; Dos referencias mutables al mismo dato son un problema de diseño.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;el-caso-de-android-un-recordatorio-util&quot;&gt;El caso de Android: un recordatorio útil&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;unsafe&lt;/code&gt; puede fallar. Google &lt;a rel=&quot;external&quot; href=&quot;https://blog.google/security/rust-in-android-move-fast-fix-things/&quot;&gt;documentó&lt;/a&gt; el caso de CVE-2025-48530, un fallo en código &lt;code&gt;unsafe&lt;/code&gt; de CrabbyAVIF, una biblioteca de Android para imágenes AVIF. Podría haber sido grave, pero se detectó antes de publicarse y un componente adicional, el asignador Scudo, lo habría hecho inexplotable.&lt;/p&gt;
&lt;p&gt;Son dos lecciones a la vez. Rust no es una garantía absoluta, y por eso sigue haciendo falta defensa en profundidad. Pero los fallos se concentran en zonas pequeñas y conocidas, en lugar de repartirse por toda la base de código.&lt;/p&gt;
&lt;h2 id=&quot;como-auditar-unsafe&quot;&gt;Cómo auditar &lt;code&gt;unsafe&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Si heredas un proyecto o evalúas una dependencia, este es un proceso razonable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Localízalo.&lt;/strong&gt; Es una de las grandes ventajas de Rust: el riesgo está marcado.&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;bash&quot;&gt;grep -rn &amp;quot;unsafe&amp;quot; src/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;2. Prohíbelo donde no haga falta.&lt;/strong&gt; Con &lt;code&gt;#![forbid(unsafe_code)]&lt;/code&gt; el compilador rechaza cualquier bloque &lt;code&gt;unsafe&lt;/code&gt;. Úsalo en todos los módulos que no lo necesiten.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Pásalo por Miri.&lt;/strong&gt; &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/miri&quot;&gt;Miri&lt;/a&gt; es la herramienta oficial que ejecuta tus pruebas e &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/book/ch20-01-unsafe-rust.html&quot;&gt;identifica comportamiento indefinido&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;bash&quot;&gt;rustup +nightly component add miri
cargo +nightly miri test
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Solo detecta lo que tus pruebas ejercitan, de modo que no reemplaza una revisión.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Revisa cada bloque con estas preguntas:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;¿Hay un comentario &lt;code&gt;SAFETY&lt;/code&gt; que explique por qué es correcto?&lt;/li&gt;
&lt;li&gt;¿Las condiciones se comprueban antes, o dependen de quien llama?&lt;/li&gt;
&lt;li&gt;¿Puede una entrada externa romper esas condiciones?&lt;/li&gt;
&lt;li&gt;¿Hay una alternativa segura de costo similar?&lt;/li&gt;
&lt;li&gt;¿La función pública es segura sin importar cómo se use?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;5. Revisa tus dependencias.&lt;/strong&gt; Tu proyecto puede no tener &lt;code&gt;unsafe&lt;/code&gt;, y aun así heredarlo de otras bibliotecas. Herramientas como &lt;code&gt;cargo audit&lt;/code&gt; y &lt;code&gt;cargo deny&lt;/code&gt; ayudan a &lt;a href=&quot;https://codigum.com/aprende/herramientas/&quot;&gt;vigilar lo que entra&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;lo-que-debes-recordar&quot;&gt;Lo que debes recordar&lt;/h2&gt;
&lt;p&gt;Cuando alguien te diga que Rust no sirve porque tiene &lt;code&gt;unsafe&lt;/code&gt;, recuerda la alternativa. En C, todo el programa es &lt;code&gt;unsafe&lt;/code&gt;, sin marcar. En Rust, la zona peligrosa tiene nombre, se puede buscar con &lt;code&gt;grep&lt;/code&gt; y cabe en una revisión.&lt;/p&gt;
&lt;p&gt;Eso no elimina el riesgo. Lo vuelve manejable.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Quién usa Rust: empresas, proyectos y plataformas</title>
        <published>2026-11-05T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/por-que-rust/quien-usa-rust/"/>
        <id>https://codigum.com/por-que-rust/quien-usa-rust/</id>
        
        <content type="html" xml:base="https://codigum.com/por-que-rust/quien-usa-rust/">&lt;p&gt;Rust ya no es una promesa. Está en el kernel de Linux, en Android, en Windows, en la infraestructura de la nube y en herramientas que millones de personas usan a diario, muchas veces sin saberlo.&lt;/p&gt;
&lt;p&gt;Esta página reúne qué hace cada empresa con Rust, y enlaza siempre a una fuente propia. Lo más reciente está en &lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/&quot;&gt;Noticias de Rust&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;donde-se-usa-rust&quot;&gt;Dónde se usa Rust&lt;/h2&gt;
&lt;p&gt;Es poco común que un mismo lenguaje cubra tanto terreno:&lt;/p&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 244&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Cinco capas donde se usa Rust, de arriba abajo: nube y servidores, web y navegador, escritorio y terminal, sistemas operativos, y embebidos y firmware.&quot;&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;0&quot; y=&quot;0&quot; width=&quot;480&quot; height=&quot;44&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__h&quot; x=&quot;16&quot; y=&quot;27&quot;&gt;Nube y servidores&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;464&quot; y=&quot;27&quot; text-anchor=&quot;end&quot;&gt;Firecracker, Pingora, Axum&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;0&quot; y=&quot;50&quot; width=&quot;480&quot; height=&quot;44&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__h&quot; x=&quot;16&quot; y=&quot;77&quot;&gt;Web y navegador&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;464&quot; y=&quot;77&quot; text-anchor=&quot;end&quot;&gt;WebAssembly, Chrome, Firefox&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;0&quot; y=&quot;100&quot; width=&quot;480&quot; height=&quot;44&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__h&quot; x=&quot;16&quot; y=&quot;127&quot;&gt;Escritorio y terminal&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;464&quot; y=&quot;127&quot; text-anchor=&quot;end&quot;&gt;Zed, Tauri, ripgrep, uv&lt;/text&gt;&lt;rect class=&quot;dg__cell&quot; x=&quot;0&quot; y=&quot;150&quot; width=&quot;480&quot; height=&quot;44&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__h&quot; x=&quot;16&quot; y=&quot;177&quot;&gt;Sistemas operativos&lt;/text&gt;&lt;text class=&quot;dg__t&quot; x=&quot;464&quot; y=&quot;177&quot; text-anchor=&quot;end&quot;&gt;Linux, Windows, Android&lt;/text&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;0&quot; y=&quot;200&quot; width=&quot;480&quot; height=&quot;44&quot; rx=&quot;10&quot;/&gt;&lt;text class=&quot;dg__h dg__on&quot; x=&quot;16&quot; y=&quot;227&quot;&gt;Embebidos y firmware&lt;/text&gt;&lt;text class=&quot;dg__t dg__on&quot; x=&quot;464&quot; y=&quot;227&quot; text-anchor=&quot;end&quot;&gt;Embassy, Tock, Hubris&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Un mismo lenguaje, desde un microcontrolador hasta un centro de datos.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Hay dos razones. Rust no necesita un entorno de ejecución ni un recolector de basura, y en sistemas embebidos &lt;a rel=&quot;external&quot; href=&quot;https://www.rust-lang.org/what/embedded&quot;&gt;la memoria dinámica es opcional&lt;/a&gt;. Además, &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/cargo/&quot;&gt;Cargo&lt;/a&gt; ofrece las mismas herramientas para compilar, probar y distribuir en todos esos entornos.&lt;/p&gt;
&lt;h2 id=&quot;en-que-plataformas-funciona&quot;&gt;En qué plataformas funciona&lt;/h2&gt;
&lt;p&gt;La &lt;a rel=&quot;external&quot; href=&quot;https://doc.rust-lang.org/rustc/platform-support.html&quot;&gt;política oficial&lt;/a&gt; clasifica las plataformas por nivel de garantía:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Nivel&lt;/th&gt;&lt;th&gt;Qué significa&lt;/th&gt;&lt;th&gt;Plataformas&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Garantizado que funciona: se prueba tras cada cambio&lt;/td&gt;&lt;td&gt;Linux y Windows en x86-64 y ARM64, macOS en Apple Silicon&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Garantizado que compila&lt;/td&gt;&lt;td&gt;Android, iOS, WebAssembly, RISC-V, microcontroladores ARM Cortex-M&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;empresas&quot;&gt;Empresas&lt;/h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Empresa&lt;/th&gt;&lt;th&gt;Qué hace con Rust&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Microsoft&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://blogs.windows.com/windows-insider/2023/07/12/announcing-windows-11-insider-preview-build-25905/&quot;&gt;Regiones GDI de Windows&lt;/a&gt; en el kernel. &lt;a rel=&quot;external&quot; href=&quot;https://techcommunity.microsoft.com/blog/windowsosplatform/openhcl-the-new-open-source-paravisor/4273172&quot;&gt;OpenVMM y OpenHCL&lt;/a&gt; en Azure. Es el &lt;a rel=&quot;external&quot; href=&quot;https://learn.microsoft.com/en-us/azure/azure-boost/overview&quot;&gt;lenguaje principal del código nuevo de Azure Boost&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Google&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Unos &lt;a rel=&quot;external&quot; href=&quot;https://blog.google/security/rust-in-android-move-fast-fix-things/&quot;&gt;5 millones de líneas en Android&lt;/a&gt;. En Chrome, &lt;a rel=&quot;external&quot; href=&quot;https://developer.chrome.com/blog/memory-safety-fonts&quot;&gt;analizadores de PNG, JSON y fuentes&lt;/a&gt;. Partes de &lt;a rel=&quot;external&quot; href=&quot;https://fuchsia.dev/fuchsia-src/contribute/governance/policy/programming_languages&quot;&gt;Fuchsia&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Amazon (AWS)&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://aws.amazon.com/blogs/aws/firecracker-lightweight-virtualization-for-serverless-computing/&quot;&gt;Firecracker&lt;/a&gt;, la base de Lambda y Fargate. &lt;a rel=&quot;external&quot; href=&quot;https://github.com/bottlerocket-os/bottlerocket&quot;&gt;Bottlerocket&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://aws.amazon.com/blogs/security/introducing-s2n-quic-open-source-protocol-rust/&quot;&gt;s2n-quic&lt;/a&gt; y &lt;a rel=&quot;external&quot; href=&quot;https://www.allthingsdistributed.com/2025/05/just-make-it-scale-an-aurora-dsql-story.html&quot;&gt;Aurora DSQL&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Cloudflare&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://blog.cloudflare.com/how-we-built-pingora-the-proxy-that-connects-cloudflare-to-the-internet/&quot;&gt;Pingora&lt;/a&gt;, que atiende más de un billón de peticiones al día, y &lt;a rel=&quot;external&quot; href=&quot;https://blog.cloudflare.com/20-percent-internet-upgrade/&quot;&gt;FL2&lt;/a&gt;, la reescritura de su sistema central.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Meta&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://engineering.fb.com/2026/01/27/security/rust-at-scale-security-whatsapp/&quot;&gt;Biblioteca de medios de WhatsApp&lt;/a&gt;, distribuida a miles de millones de dispositivos. El servidor de control de versiones &lt;a rel=&quot;external&quot; href=&quot;https://github.com/facebook/sapling/blob/main/eden/mononoke/README.md&quot;&gt;Mononoke&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Mozilla&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://firefox-source-docs.mozilla.org/layout/StyleSystemOverview.html&quot;&gt;Stylo&lt;/a&gt;, el motor CSS de Firefox.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Discord&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://discord.com/blog/why-discord-is-switching-from-go-to-rust&quot;&gt;Read States&lt;/a&gt;, servicio migrado desde Go. Lo analizamos en &lt;a href=&quot;https://codigum.com/notas/recolector-de-basura-vs-rust/&quot;&gt;esta nota&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Dropbox&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://dropbox.tech/infrastructure/rewriting-the-heart-of-our-sync-engine&quot;&gt;Nucleus&lt;/a&gt;, su motor de sincronización.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Figma&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;La &lt;a rel=&quot;external&quot; href=&quot;https://www.figma.com/blog/rust-in-production-at-figma/&quot;&gt;parte de mayor rendimiento&lt;/a&gt; de su servidor multijugador.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;1Password&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;La &lt;a rel=&quot;external&quot; href=&quot;https://1password.com/blog/1password-8-the-story-so-far&quot;&gt;biblioteca compartida&lt;/a&gt; de sus aplicaciones.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Shopify&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://shopify.engineering/ruby-yjit-is-production-ready&quot;&gt;YJIT&lt;/a&gt;, el compilador JIT de Ruby.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Vercel&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://nextjs.org/blog/next-16&quot;&gt;Turbopack&lt;/a&gt;, el empaquetador por defecto de Next.js.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Canonical&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://documentation.ubuntu.com/release-notes/26.10/&quot;&gt;Utilidades básicas con uutils&lt;/a&gt; y &lt;code&gt;sudo-rs&lt;/code&gt; en Ubuntu.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Astro&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://astro.build/blog/astro-7/&quot;&gt;Compilador &lt;code&gt;.astro&lt;/code&gt; y procesador de Markdown&lt;/a&gt; desde la versión 7.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Git&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://git-scm.com/docs/BreakingChanges&quot;&gt;Rust activado por defecto&lt;/a&gt;, y obligatorio para compilar en Git 3.0.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Signal&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/signalapp/libsignal&quot;&gt;libsignal&lt;/a&gt;, usada por sus aplicaciones y sus servidores.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;y-apple&quot;&gt;¿Y Apple?&lt;/h2&gt;
&lt;p&gt;Es la gran ausente, y vale la pena explicar por qué. No encontramos ninguna publicación ni repositorio de Apple que confirme Rust en sus productos. Lo que circula son ofertas de empleo y rumores, así que no la incluimos en la lista.&lt;/p&gt;
&lt;p&gt;Lo interesante es que Apple persigue el mismo objetivo por otro camino. En 2025 &lt;a rel=&quot;external&quot; href=&quot;https://security.apple.com/blog/memory-integrity-enforcement/&quot;&gt;explicó&lt;/a&gt; que usa Swift, su propio lenguaje seguro en memoria, para código nuevo y reescrituras puntuales, junto con protecciones de hardware en el iPhone 17. Y Rust funciona muy bien para quien desarrolla en sus equipos: macOS en Apple Silicon es una plataforma de nivel 1.&lt;/p&gt;
&lt;h2 id=&quot;proyectos&quot;&gt;Proyectos&lt;/h2&gt;
&lt;p&gt;Todos estos proyectos abiertos tienen Rust como lenguaje principal en su repositorio, y estaban activos en noviembre de 2026.&lt;/p&gt;
&lt;h3 id=&quot;sistemas-operativos-y-virtualizacion&quot;&gt;Sistemas operativos y virtualización&lt;/h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Proyecto&lt;/th&gt;&lt;th&gt;Qué es&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/torvalds/linux/commit/9fa7153c31a3e5fe578b83d23bc9f185fde115da&quot;&gt;Linux&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Rust dejó de ser un experimento en el kernel. Es opcional, y ya hay drivers como &lt;code&gt;nova-core&lt;/code&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/redox-os/redox&quot;&gt;Redox OS&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Sistema operativo tipo Unix, escrito desde cero.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/asterinas/asterinas&quot;&gt;Asterinas&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Kernel compatible con Linux.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/firecracker-microvm/firecracker&quot;&gt;Firecracker&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Micromáquinas virtuales para funciones en la nube.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/microsoft/openvmm&quot;&gt;OpenVMM&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Monitor de máquinas virtuales de Microsoft.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/bottlerocket-os/bottlerocket&quot;&gt;Bottlerocket&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Sistema operativo de AWS para contenedores.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;embebidos-y-firmware&quot;&gt;Embebidos y firmware&lt;/h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Proyecto&lt;/th&gt;&lt;th&gt;Qué es&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/embassy-rs/embassy&quot;&gt;Embassy&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Framework asíncrono para microcontroladores.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/tock/tock&quot;&gt;Tock&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Sistema operativo para dispositivos con pocos recursos.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/oxidecomputer/hubris&quot;&gt;Hubris&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Sistema operativo para microcontroladores, de Oxide Computer.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;frameworks-y-bibliotecas&quot;&gt;Frameworks y bibliotecas&lt;/h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Proyecto&lt;/th&gt;&lt;th&gt;Qué es&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/tokio-rs/tokio&quot;&gt;Tokio&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Entorno asíncrono, base de gran parte del ecosistema.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/tokio-rs/axum&quot;&gt;Axum&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/actix/actix-web&quot;&gt;Actix Web&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rwf2/Rocket&quot;&gt;Rocket&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Frameworks web.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/hyperium/hyper&quot;&gt;Hyper&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Implementación de HTTP.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/serde-rs/serde&quot;&gt;Serde&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Serialización de datos.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/rayon-rs/rayon&quot;&gt;Rayon&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Paralelismo de datos.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/leptos-rs/leptos&quot;&gt;Leptos&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/DioxusLabs/dioxus&quot;&gt;Dioxus&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Interfaces web y multiplataforma.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/tauri-apps/tauri&quot;&gt;Tauri&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Aplicaciones de escritorio y móviles.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/bevyengine/bevy&quot;&gt;Bevy&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Motor de videojuegos.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/PyO3/pyo3&quot;&gt;PyO3&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Puente entre Rust y Python.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;herramientas-de-linea-de-comandos&quot;&gt;Herramientas de línea de comandos&lt;/h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Proyecto&lt;/th&gt;&lt;th&gt;Qué es&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/BurntSushi/ripgrep&quot;&gt;ripgrep&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Búsqueda en archivos. Es el motor de búsqueda de muchos editores.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/sharkdp/fd&quot;&gt;fd&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/sharkdp/bat&quot;&gt;bat&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Alternativas modernas a &lt;code&gt;find&lt;/code&gt; y &lt;code&gt;cat&lt;/code&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/trifectatechfoundation/sudo-rs&quot;&gt;sudo-rs&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/uutils/coreutils&quot;&gt;uutils&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;sudo&lt;/code&gt; y utilidades básicas de sistema.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/fish-shell/fish-shell&quot;&gt;fish&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/nushell/nushell&quot;&gt;Nushell&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Intérpretes de comandos.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/starship/starship&quot;&gt;Starship&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Línea de comandos personalizable.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;herramientas-de-desarrollo&quot;&gt;Herramientas de desarrollo&lt;/h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Proyecto&lt;/th&gt;&lt;th&gt;Qué es&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/rust-lang/cargo&quot;&gt;Cargo&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Gestor de paquetes de Rust.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/astral-sh/uv&quot;&gt;uv&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/astral-sh/ruff&quot;&gt;Ruff&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Gestor de paquetes y analizador para Python.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/biomejs/biome&quot;&gt;Biome&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/swc-project/swc&quot;&gt;SWC&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/rolldown/rolldown&quot;&gt;Rolldown&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Herramientas para JavaScript y TypeScript.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/denoland/deno&quot;&gt;Deno&lt;/a&gt;, &lt;a href=&quot;https://codigum.com/notas/noticias-de-rust/#bun&quot;&gt;Bun&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Entornos de ejecución de JavaScript.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;aplicaciones&quot;&gt;Aplicaciones&lt;/h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Proyecto&lt;/th&gt;&lt;th&gt;Qué es&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/zed-industries/zed&quot;&gt;Zed&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/helix-editor/helix&quot;&gt;Helix&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Editores de código.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/alacritty/alacritty&quot;&gt;Alacritty&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Terminal con aceleración gráfica.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/servo/servo&quot;&gt;Servo&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Motor de navegador.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/typst/typst&quot;&gt;Typst&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Sistema de composición de documentos.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/rustdesk/rustdesk&quot;&gt;RustDesk&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Escritorio remoto.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;datos-e-infraestructura&quot;&gt;Datos e infraestructura&lt;/h3&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Proyecto&lt;/th&gt;&lt;th&gt;Qué es&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/tikv/tikv&quot;&gt;TiKV&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Base de datos distribuida de clave y valor.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/pola-rs/polars&quot;&gt;Polars&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Análisis de datos tabulares.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/qdrant/qdrant&quot;&gt;Qdrant&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Base de datos vectorial.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/meilisearch/meilisearch&quot;&gt;Meilisearch&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Motor de búsqueda.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/MaterializeInc/materialize&quot;&gt;Materialize&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Base de datos de flujos en tiempo real.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/neondatabase/neon&quot;&gt;Neon&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Postgres en la nube.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/vectordotdev/vector&quot;&gt;Vector&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Canalización de datos de observabilidad.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/linkerd/linkerd2-proxy&quot;&gt;Linkerd&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Proxy de malla de servicios.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h3 id=&quot;blockchain&quot;&gt;Blockchain&lt;/h3&gt;
&lt;p&gt;Es un sector donde Rust encaja bien: un fallo puede costar dinero real, y el código se ejecuta a alta velocidad.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Proyecto&lt;/th&gt;&lt;th&gt;Qué es&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/paradigmxyz/reth&quot;&gt;Reth&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/sigp/lighthouse&quot;&gt;Lighthouse&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Clientes de Ethereum, de ejecución y de consenso.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/anza-xyz/agave&quot;&gt;Agave&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Cliente validador de Solana.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https://docs.polkadot.com/develop/parachains/intro-polkadot-sdk&quot;&gt;Polkadot SDK&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Kit para construir cadenas de bloques.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;lo-que-esta-lista-no-dice&quot;&gt;Lo que esta lista no dice&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Usar Rust no significa reescribirlo todo.&lt;/strong&gt; Casi todas estas empresas lo adoptaron por partes. Figma, por ejemplo, solo movió la parte más exigente.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rust no evita todos los fallos.&lt;/strong&gt; La &lt;a rel=&quot;external&quot; href=&quot;https://blog.cloudflare.com/18-november-2025-outage&quot;&gt;caída de Cloudflare del 18 de noviembre de 2025&lt;/a&gt; se produjo por un pánico en código Rust. Un error de lógica sigue siendo un error.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rust no es la única salida.&lt;/strong&gt; Apple resuelve el mismo problema con Swift, y varios lenguajes con recolector también son seguros en memoria.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cada lenguaje tiene su lugar.&lt;/strong&gt; Python sigue siendo ideal para explorar datos, y muchas aplicaciones de negocio van muy bien con Java o C#.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Esta lista envejece.&lt;/strong&gt; Es una foto de noviembre de 2026. Enlazamos las fuentes para que puedas revisarlas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si estás pensando en adoptar Rust, empieza por &lt;a href=&quot;https://codigum.com/por-que-rust/&quot;&gt;la evidencia&lt;/a&gt; y por &lt;a href=&quot;https://codigum.com/notas/vale-la-pena-migrar-a-rust/&quot;&gt;las cinco preguntas antes de migrar&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>El 70 %: qué es la seguridad de memoria y por qué importa</title>
        <published>2026-11-04T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/que-es-seguridad-de-memoria/"/>
        <id>https://codigum.com/notas/que-es-seguridad-de-memoria/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/que-es-seguridad-de-memoria/">&lt;p&gt;En 2019, Microsoft publicó un dato incómodo: &lt;a rel=&quot;external&quot; href=&quot;https://www.microsoft.com/en-us/msrc/blog/2019/07/a-proactive-approach-to-more-secure-code&quot;&gt;alrededor del 70 %&lt;/a&gt; de los CVE que asigna cada año son fallos de seguridad de memoria. No son errores de un equipo descuidado, sino el resultado de décadas de software en C y C++, escrito por excelentes ingenieros.&lt;/p&gt;
&lt;p&gt;Google vio un patrón parecido, y la &lt;a rel=&quot;external&quot; href=&quot;https://media.defense.gov/2022/Nov/10/2003112742/-1/-1/0/CSI_SOFTWARE_MEMORY_SAFETY.PDF&quot;&gt;NSA citó ambos casos&lt;/a&gt; al recomendar lenguajes seguros en memoria.&lt;/p&gt;
&lt;h2 id=&quot;que-es-un-fallo-de-memoria&quot;&gt;Qué es un fallo de memoria&lt;/h2&gt;
&lt;p&gt;Un programa guarda datos en memoria y accede a ellos por su dirección. Hay un fallo cuando lee o escribe donde no debe. Dos ejemplos clásicos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/#desbordamiento&quot;&gt;Desbordamiento de búfer&lt;/a&gt;:&lt;/strong&gt; se escribe más allá del espacio reservado, y se pisan datos vecinos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/#uaf&quot;&gt;Uso después de liberar&lt;/a&gt;:&lt;/strong&gt; se usa memoria que ya se devolvió al sistema, y que quizá ya contiene otra cosa.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 480 172&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Primero s apunta a tu dato. Luego la memoria se libera, pero s sigue apuntando ahí. Al final, otra parte del programa la reutiliza y s lee datos ajenos.&quot;&gt;&lt;text class=&quot;dg__h&quot; x=&quot;0&quot; y=&quot;18&quot;&gt;1. Reservas&lt;/text&gt;&lt;text class=&quot;dg__c&quot; x=&quot;74&quot; y=&quot;50&quot;&gt;s&lt;/text&gt;&lt;path class=&quot;dg__ptr&quot; d=&quot;M74 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__own&quot; x=&quot;0&quot; y=&quot;88&quot; width=&quot;148&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;74&quot; y=&quot;117.5&quot;&gt;tu dato&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid&quot; x=&quot;74&quot; y=&quot;160&quot;&gt;s es válido&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;166&quot; y=&quot;18&quot;&gt;2. Liberas&lt;/text&gt;&lt;text class=&quot;dg__c&quot; x=&quot;240&quot; y=&quot;50&quot;&gt;s&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--bad&quot; d=&quot;M240 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__free&quot; x=&quot;166&quot; y=&quot;88&quot; width=&quot;148&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c dg__mm&quot; x=&quot;240&quot; y=&quot;117.5&quot;&gt;libre&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__tbad&quot; x=&quot;240&quot; y=&quot;160&quot;&gt;s sigue apuntando&lt;/text&gt;&lt;text class=&quot;dg__h&quot; x=&quot;332&quot; y=&quot;18&quot;&gt;3. Otro la reutiliza&lt;/text&gt;&lt;text class=&quot;dg__c&quot; x=&quot;406&quot; y=&quot;50&quot;&gt;s&lt;/text&gt;&lt;path class=&quot;dg__ptr dg__ptr--bad&quot; d=&quot;M406 56V84m-5-7 5 7 5-7&quot;/&gt;&lt;rect class=&quot;dg__risk&quot; x=&quot;332&quot; y=&quot;88&quot; width=&quot;148&quot; height=&quot;48&quot; rx=&quot;8&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;406&quot; y=&quot;117.5&quot;&gt;dato ajeno&lt;/text&gt;&lt;text class=&quot;dg__t dg__mid dg__tbad&quot; x=&quot;406&quot; y=&quot;160&quot;&gt;s lee datos ajenos&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;El puntero parece válido, pero la memoria ya pertenece a otra parte del programa.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;Este código en C compila, aunque es incorrecto:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;c&quot;&gt;char *s = malloc(16);
free(s);
s[0] = &amp;#39;x&amp;#39;; // uso después de liberar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Un atacante que controle lo que ocupa esa memoria puede llegar a leer datos o a ejecutar su propio código. Hay más fallos de esta familia, y los ilustramos uno por uno en &lt;a href=&quot;https://codigum.com/notas/fallos-de-memoria-ilustrados/&quot;&gt;Los 7 fallos de memoria más comunes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;que-cambia-con-rust&quot;&gt;Qué cambia con Rust&lt;/h2&gt;
&lt;p&gt;La misma idea no compila en Rust:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;fn main() {
    let r;
    {
        let s = String::from(&amp;quot;hola&amp;quot;);
        r = &amp;amp;s;
    } // `s` se libera aquí
    println!(&amp;quot;{r}&amp;quot;); // error[E0597]: `s` does not live long enough
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El error se detecta antes de ejecutar el programa, sin importar lo cansado que estuviera quien lo escribió. Es la diferencia entre pedir cuidado y hacer imposible el error.&lt;/p&gt;
&lt;h2 id=&quot;los-resultados&quot;&gt;Los resultados&lt;/h2&gt;
&lt;p&gt;Android es el caso más documentado. Google &lt;a rel=&quot;external&quot; href=&quot;https://blog.google/security/rust-in-android-move-fast-fix-things/&quot;&gt;informa&lt;/a&gt; que los fallos de memoria bajaron del 20 % de sus vulnerabilidades por primera vez en 2025, a medida que el código nuevo dejó de escribirse en C y C++.&lt;/p&gt;
&lt;h2 id=&quot;los-limites&quot;&gt;Los límites&lt;/h2&gt;
&lt;p&gt;Rust no resuelve todo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El código marcado como &lt;code&gt;unsafe&lt;/code&gt; queda bajo tu responsabilidad. Android tuvo un fallo de este tipo (CVE-2025-48530), detectado antes de su publicación.&lt;/li&gt;
&lt;li&gt;Los errores de lógica, de autorización y las dependencias comprometidas siguen siendo posibles.&lt;/li&gt;
&lt;li&gt;Java, C#, Go y Python también son seguros en memoria, gracias a un &lt;a href=&quot;https://codigum.com/notas/recolector-de-basura-vs-rust/&quot;&gt;recolector de basura que tiene su propio costo&lt;/a&gt;. Esta cifra describe sobre todo a C y C++.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La seguridad nunca depende de una sola decisión. Pero eliminar una clase entera de errores desde el diseño es de las pocas mejoras que no se desgastan con el tiempo.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Cómo adoptar Rust en un sistema C++ existente</title>
        <published>2026-11-03T00:00:00+00:00</published>
        <updated>2026-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/adoptar-rust-en-cpp/"/>
        <id>https://codigum.com/notas/adoptar-rust-en-cpp/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/adoptar-rust-en-cpp/">&lt;p&gt;Reescribir un sistema grande de C++ de una sola vez es arriesgado y rara vez es necesario. Una estrategia gradual reduce el riesgo desde la primera entrega.&lt;/p&gt;
&lt;h2 id=&quot;empieza-por-el-codigo-nuevo&quot;&gt;Empieza por el código nuevo&lt;/h2&gt;
&lt;p&gt;Google observó en Android que las vulnerabilidades de memoria se concentran en el código nuevo. Por eso, escribir las funciones nuevas en un lenguaje seguro en memoria puede aportar mucho sin tocar el código antiguo y ya probado.&lt;/p&gt;
&lt;h2 id=&quot;prioriza-por-exposicion&quot;&gt;Prioriza por exposición&lt;/h2&gt;
&lt;p&gt;No todo el código tiene el mismo riesgo. Empieza por lo que recibe datos no confiables: parsers, decodificadores, protocolos de red y límites entre procesos.&lt;/p&gt;
&lt;h2 id=&quot;elige-como-conectar-ambos-lenguajes&quot;&gt;Elige cómo conectar ambos lenguajes&lt;/h2&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 560 150&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;El código C++ existente y el código nuevo en Rust se comunican a través de cxx.&quot;&gt;&lt;rect class=&quot;dg__box&quot; x=&quot;0&quot; y=&quot;26&quot; width=&quot;200&quot; height=&quot;98&quot; rx=&quot;16&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;100&quot; y=&quot;70&quot;&gt;C++&lt;/text&gt;&lt;text class=&quot;dg__c dg__m&quot; x=&quot;100&quot; y=&quot;96&quot;&gt;código existente&lt;/text&gt;&lt;path class=&quot;dg__axis&quot; d=&quot;M208 62H352m-8-6 8 6-8 6M352 90H208m8-6-8 6 8 6&quot;/&gt;&lt;text class=&quot;dg__c dg__m&quot; x=&quot;280&quot; y=&quot;48&quot;&gt;cxx&lt;/text&gt;&lt;rect class=&quot;dg__ok&quot; x=&quot;360&quot; y=&quot;26&quot; width=&quot;200&quot; height=&quot;98&quot; rx=&quot;16&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;460&quot; y=&quot;70&quot;&gt;Rust&lt;/text&gt;&lt;text class=&quot;dg__c dg__on dg__s&quot; x=&quot;460&quot; y=&quot;96&quot;&gt;código nuevo&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Una frontera pequeña y clara: es lo único que ambos lados deben acordar.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://cxx.rs&quot;&gt;&lt;code&gt;cxx&lt;/code&gt;&lt;/a&gt; genera puentes seguros entre Rust y C++ a partir de una interfaz declarada.&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://rust-lang.github.io/rust-bindgen/&quot;&gt;&lt;code&gt;bindgen&lt;/code&gt;&lt;/a&gt; genera enlaces a partir de cabeceras C y C++, lo que suele ser útil con APIs amplias.&lt;/li&gt;
&lt;li&gt;Una frontera C explícita es más manual, pero también más estable y fácil de auditar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mantén la frontera pequeña y bien definida. Cada cruce es código &lt;code&gt;unsafe&lt;/code&gt; que hay que revisar.&lt;/p&gt;
&lt;h2 id=&quot;envuelve-lo-inseguro&quot;&gt;Envuelve lo inseguro&lt;/h2&gt;
&lt;p&gt;Encierra el código &lt;code&gt;unsafe&lt;/code&gt; en módulos pequeños que expongan una interfaz segura, y documenta qué condiciones debe cumplir cada bloque.&lt;/p&gt;
&lt;p&gt;Rust no elimina todo el riesgo. Google informó de un desbordamiento de búfer en código Rust &lt;code&gt;unsafe&lt;/code&gt; de Android (CVE-2025-48530), detectado antes de llegar a una versión pública.&lt;/p&gt;
&lt;h2 id=&quot;integra-la-construccion&quot;&gt;Integra la construcción&lt;/h2&gt;
&lt;p&gt;Define desde el inicio cómo convivirán CMake o Bazel con Cargo, cómo se ejecutarán las pruebas de ambos lenguajes y cómo se gestionarán las dependencias. Muchos retrasos vienen de aquí, no del lenguaje.&lt;/p&gt;
&lt;h2 id=&quot;mide-el-avance&quot;&gt;Mide el avance&lt;/h2&gt;
&lt;p&gt;Registra vulnerabilidades, reversiones y tiempo de revisión antes y después. Esos datos permiten decidir si conviene ampliar la adopción.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>Cómo migrar de Python a Rust sin reescribir tu aplicación</title>
        <published>2026-11-03T00:00:00+00:00</published>
        <updated>2026-11-03T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/migrar-de-python-a-rust/"/>
        <id>https://codigum.com/notas/migrar-de-python-a-rust/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/migrar-de-python-a-rust/">&lt;p&gt;No necesitas elegir entre Python y Rust. Casi siempre conviene usar los dos: Python para orquestar y Rust para las pocas rutas donde se concentra el costo.&lt;/p&gt;
&lt;p&gt;Herramientas como &lt;a rel=&quot;external&quot; href=&quot;https://pola.rs&quot;&gt;Polars&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://docs.astral.sh/ruff/&quot;&gt;Ruff&lt;/a&gt; y &lt;a rel=&quot;external&quot; href=&quot;https://docs.astral.sh/uv/&quot;&gt;uv&lt;/a&gt; siguen esta idea: se usan desde el ecosistema de Python, con un núcleo escrito en Rust.&lt;/p&gt;
&lt;h2 id=&quot;1-mide-antes-de-migrar&quot;&gt;1. Mide antes de migrar&lt;/h2&gt;
&lt;p&gt;Rust no arregla un problema que no has localizado. Perfila tu aplicación con carga real, usando una herramienta como &lt;a rel=&quot;external&quot; href=&quot;https://github.com/benfred/py-spy&quot;&gt;py-spy&lt;/a&gt;, y busca funciones de CPU que dominen el tiempo total.&lt;/p&gt;
&lt;p&gt;Si el tiempo se va esperando a la base de datos o a la red, Rust no ayudará mucho. Corrige primero las consultas, los índices o la arquitectura.&lt;/p&gt;
&lt;h2 id=&quot;2-elige-una-funcion-pequena-y-pura&quot;&gt;2. Elige una función pequeña y pura&lt;/h2&gt;
&lt;p&gt;El mejor primer candidato tiene tres rasgos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Consume mucha CPU.&lt;/li&gt;
&lt;li&gt;Tiene entradas y salidas simples.&lt;/li&gt;
&lt;li&gt;Tiene pruebas, o es fácil escribírselas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Parsers, validadores, transformaciones de datos y cálculos numéricos suelen encajar bien.&lt;/p&gt;
&lt;h2 id=&quot;3-exponla-como-un-modulo-de-python&quot;&gt;3. Exponla como un módulo de Python&lt;/h2&gt;
&lt;figure class=&quot;dg&quot;&gt;&lt;svg viewBox=&quot;0 0 560 150&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;La aplicación Python llama a un núcleo en Rust a través de PyO3 y recibe los resultados.&quot;&gt;&lt;rect class=&quot;dg__box&quot; x=&quot;0&quot; y=&quot;26&quot; width=&quot;200&quot; height=&quot;98&quot; rx=&quot;16&quot;/&gt;&lt;text class=&quot;dg__c&quot; x=&quot;100&quot; y=&quot;70&quot;&gt;Python&lt;/text&gt;&lt;text class=&quot;dg__c dg__m&quot; x=&quot;100&quot; y=&quot;96&quot;&gt;tu aplicación&lt;/text&gt;&lt;path class=&quot;dg__axis&quot; d=&quot;M208 62H352m-8-6 8 6-8 6M352 90H208m8-6-8 6 8 6&quot;/&gt;&lt;text class=&quot;dg__c dg__m&quot; x=&quot;280&quot; y=&quot;48&quot;&gt;PyO3&lt;/text&gt;&lt;rect class=&quot;dg__ok&quot; x=&quot;360&quot; y=&quot;26&quot; width=&quot;200&quot; height=&quot;98&quot; rx=&quot;16&quot;/&gt;&lt;text class=&quot;dg__c dg__on&quot; x=&quot;460&quot; y=&quot;70&quot;&gt;Rust&lt;/text&gt;&lt;text class=&quot;dg__c dg__on dg__s&quot; x=&quot;460&quot; y=&quot;96&quot;&gt;solo lo crítico&lt;/text&gt;&lt;/svg&gt;&lt;figcaption&gt;Una frontera pequeña y clara: es lo único que ambos lados deben acordar.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://pyo3.rs&quot;&gt;PyO3&lt;/a&gt; permite escribir extensiones nativas, y &lt;a rel=&quot;external&quot; href=&quot;https://www.maturin.rs&quot;&gt;maturin&lt;/a&gt; las empaqueta. Desde Python, se importa como cualquier otro módulo:&lt;/p&gt;
&lt;pre&gt;&lt;code data-lang=&quot;rust&quot;&gt;use pyo3::prelude::*;

#[pyfunction]
fn total_centavos(montos: Vec&amp;lt;i64&amp;gt;) -&amp;gt; i64 {
    montos.iter().sum()
}

#[pymodule]
fn nucleo(m: &amp;amp;Bound&amp;lt;&amp;#39;_, PyModule&amp;gt;) -&amp;gt; PyResult&amp;lt;()&amp;gt; {
    m.add_function(wrap_pyfunction!(total_centavos, m)?)?;
    Ok(())
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code data-lang=&quot;python&quot;&gt;import nucleo

nucleo.total_centavos([1250, 800, 4300])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cruzar la frontera entre Python y Rust también cuesta tiempo, porque se convierten datos. Por eso es mejor pasar lotes de trabajo que llamar a Rust una vez por cada elemento en un bucle.&lt;/p&gt;
&lt;h2 id=&quot;4-verifica-la-equivalencia&quot;&gt;4. Verifica la equivalencia&lt;/h2&gt;
&lt;p&gt;Ejecuta la versión antigua y la nueva con las mismas entradas y compara los resultados. En producción, puedes correr ambas en paralelo durante un tiempo y usar solo la antigua para responder, hasta tener confianza.&lt;/p&gt;
&lt;h2 id=&quot;5-decide-si-seguir&quot;&gt;5. Decide si seguir&lt;/h2&gt;
&lt;p&gt;Compara el resultado con la métrica que definiste al inicio. Si la mejora justifica el costo, pasa al siguiente componente. Si no, detente: una migración parcial que resuelve el problema ya es un buen resultado.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="es">
        <title>¿Vale la pena migrar a Rust? Cinco preguntas antes de decidir</title>
        <published>2026-11-03T00:00:00+00:00</published>
        <updated>2026-11-05T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://codigum.com/notas/vale-la-pena-migrar-a-rust/"/>
        <id>https://codigum.com/notas/vale-la-pena-migrar-a-rust/</id>
        
        <content type="html" xml:base="https://codigum.com/notas/vale-la-pena-migrar-a-rust/">&lt;p&gt;Rust es una gran herramienta, pero migrar cuesta tiempo, dinero y atención. Antes de decidir, conviene responder cinco preguntas.&lt;/p&gt;
&lt;h2 id=&quot;1-que-problema-concreto-quieres-resolver&quot;&gt;1. ¿Qué problema concreto quieres resolver?&lt;/h2&gt;
&lt;p&gt;&quot;Queremos usar Rust&quot; no es un objetivo. &quot;Reducir la latencia del cálculo de riesgo&quot; o &quot;eliminar una clase de vulnerabilidades en nuestro parser&quot; sí lo son.&lt;/p&gt;
&lt;p&gt;Si no puedes medir el problema, tampoco podrás saber si lo resolviste.&lt;/p&gt;
&lt;h2 id=&quot;2-de-que-lenguaje-vienes&quot;&gt;2. ¿De qué lenguaje vienes?&lt;/h2&gt;
&lt;p&gt;La respuesta cambia por completo el argumento:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Desde C o C++&lt;/strong&gt;, la seguridad de memoria es el beneficio principal.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Desde Java, C# o Python&lt;/strong&gt;, ya tienes seguridad de memoria. El beneficio estará en el rendimiento, &lt;a href=&quot;https://codigum.com/notas/recolector-de-basura-vs-rust/&quot;&gt;los picos de latencia&lt;/a&gt;, el &lt;a href=&quot;https://codigum.com/notas/huella-de-carbono-del-software/&quot;&gt;consumo de recursos&lt;/a&gt; o la robustez del diseño.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Migrar desde Java &quot;por seguridad&quot; suele ser un mal argumento. Una auditoría de la aplicación probablemente dará más resultados.&lt;/p&gt;
&lt;h2 id=&quot;3-donde-se-va-realmente-el-tiempo&quot;&gt;3. ¿Dónde se va realmente el tiempo?&lt;/h2&gt;
&lt;p&gt;Si tu sistema pasa la mayor parte del tiempo esperando a la base de datos, un lenguaje más rápido cambiará poco. Mide primero.&lt;/p&gt;
&lt;h2 id=&quot;4-quien-mantendra-el-codigo&quot;&gt;4. ¿Quién mantendrá el código?&lt;/h2&gt;
&lt;p&gt;Rust tiene una &lt;a href=&quot;https://codigum.com/notas/cuanto-tarda-un-equipo-en-aprender-rust/&quot;&gt;curva de aprendizaje real&lt;/a&gt;. Sin un plan para formar a tu equipo, dependerás de quienes lo escribieron. Inclúyelo en el costo desde el inicio.&lt;/p&gt;
&lt;h2 id=&quot;5-puedes-migrar-por-partes&quot;&gt;5. ¿Puedes migrar por partes?&lt;/h2&gt;
&lt;p&gt;Las migraciones que mejor funcionan empiezan con un componente pequeño y medible. Si tu sistema no se puede separar, quizá el primer proyecto sea modularizarlo.&lt;/p&gt;
&lt;h2 id=&quot;lo-que-rust-no-resuelve&quot;&gt;Lo que Rust no resuelve&lt;/h2&gt;
&lt;p&gt;Rust evita muchos errores de memoria y carreras de datos, pero no impide los errores de lógica, los problemas de autorización ni las dependencias comprometidas. Sigue siendo necesario revisar, probar y auditar.&lt;/p&gt;
&lt;h2 id=&quot;entonces-cuando-si&quot;&gt;Entonces, ¿cuándo sí?&lt;/h2&gt;
&lt;p&gt;Rust suele tener sentido cuando se dan estas condiciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tienes código crítico expuesto a datos no confiables, en C o C++.&lt;/li&gt;
&lt;li&gt;El rendimiento o el costo de infraestructura es un problema medido.&lt;/li&gt;
&lt;li&gt;Puedes empezar por un componente acotado.&lt;/li&gt;
&lt;li&gt;Tu equipo está dispuesto a aprender.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si no se cumple ninguna, lo más honesto es no migrar.&lt;/p&gt;
</content>
        
    </entry>
</feed>
