Cloudflare ha logrado reducir aproximadamente 100 TB de consumo acumulado de memoria en su infraestructura que soporta la plataforma DNS Big Pineapple, tras modificar la forma en que representa y almacena en RAM las entradas de caché. Este avance no proviene de añadir nuevos servidores, sino de implementar cinco cambios consecutivos en estructuras de datos escritas en Rust, que han reducido en un 56 % la huella de memoria por entrada y, al mismo tiempo, mejorado el rendimiento de la caché.
Resumen de la optimización de Cloudflare en 30 segundos
- Big Pineapple mantiene en caché más de 250.000 millones de entradas DNS para servicios como 1.1.1.1, Gateway DNS y DNS Firewall.
- Cloudflare redujo el tamaño medio de cada entrada de 953 a 420 bytes, una disminución del 56 %.
- Este ahorro equivale a aproximadamente 100 TB de memoria, comparable a la RAM de unos 130 servidores Gen 13 de la compañía.
- Las tasas de inserción aumentaron un 43 % y la latencia de consulta se redujo en un 19 %.
- Gran parte de la mejora proviene de reducir asignaciones, eliminar datos redundantes y almacenar registros DNS de forma más compacta.
Este caso es especialmente interesante para administradores de sistemas y desarrolladores porque demuestra cómo unos pocos bytes pueden marcar una gran diferencia cuando se gestionan a escala. Big Pineapple mantiene en caché más de 250.000 millones de elementos en cualquier momento. En un volumen tan grande, un solo byte desperdiciado por entrada puede significar más de 250 GB de memoria en toda la infraestructura.
Cloudflare empezó a implementar estos cambios desde el 18 de mayo de 2026 y completó su despliegue en todos los servicios el 6 de julio. Los resultados se midieron tanto mediante benchmarks como observando el consumo de memoria en instancias en producción.
De Vec y String a estructuras que ocupan exactamente lo necesario
Una entrada de caché DNS contiene mucha más información que solo una dirección IP. Big Pineapple almacena la consulta, el tipo de registro, datos de autenticación, respuestas DNS, registros de autoridad e información adicional, además de metadatos como el tiempo de creación, el número de accesos y el TTL (Time to Live).
Una de las primeras mejoras partió del uso de una característica común en Rust.
Un Vec<t> necesita mantener tres datos: un puntero a los elementos, su longitud actual y su capacidad de almacenamiento. La capacidad adicional resulta imprescindible cuando una colección puede crecer.
El problema es que una respuesta DNS almacenada en la caché de Cloudflare ya no cambia después de insertarse.
Por lo tanto, mantener capacidad adicional para futuros elementos era redundante.
Cloudflare reemplazó varios Vec<t> por Box<[T]>, una estructura de tamaño fijo que no requiere reservar capacidad extra. También aplicaron una idea similar a las cadenas de texto, sustituyendo ciertos String por Box<str>.
Cada entrada contenía ocho campos de estos tipos. Eliminar ocho bytes por campo permitió ahorrar 64 bytes por entrada, además del espacio que los vectores podrían haber reservado y no utilizaban.
A escala de toda la plataforma, solo este cambio representa más de 15 TB de memoria según cálculos de Cloudflare.
Este ejemplo muestra cómo el análisis del consumo en servicios a gran escala puede revelar que estructuras normalmente aceptables para aplicaciones convencionales pueden ser demasiado costosas cuando se gestionan cientos de miles de millones de objetos.
Menos listas y menos punteros
Cloudflare también revisó cómo almacenaba las tres principales secciones de una respuesta DNS: respuesta, autoridad e información adicional.
Originalmente, cada sección tenía su propia lista independiente.
La nueva implementación usa una única colección de registros y pequeños desplazamientos para indicar dónde empieza cada sección.
Dado que el número de registros puede representarse con valores u16, cada desplazamiento requiere solo dos bytes.
Esta modificación permite ahorrar aproximadamente 28 bytes por entrada al eliminar las dos listas independientes con sus punteros y longitudes.
Además, la programación a bajo nivel implica que Rust introduce padding para alinear correctamente ciertos campos, por lo que reorganizar o eliminar campos pequeños también puede generar ahorros superiores al tamaño aparente de los datos.
Para optimizar aún más, Cloudflare agrupó varios valores booleanos mediante bitflags, reduciendo el tamaño total.
Eliminación de información redundante y reducción del coste de los enum en Rust
Otra de las mejoras se centró en el propietario de cada registro DNS.
Una consulta para un registro A suele devolver registros cuyo propietario coincide exactamente con el dominio consultado. Guardar de forma repetida ese nombre en cada registro duplicaba información que ya está en la clave de caché.
Cloudflare decidió dejar de almacenarlo cuando ambos valores coinciden, conservando explícitamente solo cuando son diferentes, como puede ocurrir tras seguir un registro CNAME.
Al reconstruir la respuesta, Big Pineapple recupera el dominio original desde la clave de caché, lo que reduce el uso de memoria y las asignaciones en heap en los casos más frecuentes.
Este enfoque también tiene beneficios desde el punto de vista de Rust.
Un enum puede tener variantes de tamaños diferentes, pero toda la estructura reserva espacio para la variante más grande.
Cloudflare tenía una representación como esta:
pub enum RecordData {
A(Ipv4Addr),
Aaaa(Ipv6Addr),
Txt(Txt),
Naptr(Naptr),
Svcb(Svcb),
}El problema estaba en NAPTR. Su estructura podía necesitar unos 136 bytes, haciendo que el enum ocupara hasta 144 bytes, sumando identificador y alineación.
En cambio, un registro IPv4 A solo requiere 4 bytes, y uno AAAA necesita 16.
Esa diferencia es significativa porque los registros A y AAAA representan más del 80 % del tráfico en las pruebas de Cloudflare.
Box para solucionar parte del problema, pero introduce otros
Una primera solución fue mantener los registros pequeños directamente en el enum y colocar los registros grandes en memoria dinámica mediante Box.
Esto redujo el tamaño de la estructura principal.
Pero surgió un nuevo coste: cada Box necesita una asignación en heap. Cloudflare usa jemalloc, que agrupa asignaciones en clases de tamaño, lo que puede generar ligeras sobreasignaciones.
Más importante aún, hay un impacto en la CPU: distribuir datos por diferentes zonas del heap hace que el procesador tenga que seguir punteros, lo que puede resultar en accesos menos eficientes a la memoria caché debido a la dispersión de los datos.
En definitiva, ahorrar memoria puede afectar la localidad de los datos.
Por eso, Cloudflare continúa explorando otras maneras de representar los datos.
Almacenar parte del DNS en un formato cercano a cómo viaja por la red mejora memoria y velocidad
La solución final consistió en aproximarse al formato binario ejecutado por DNS.
Consideraron almacenar directamente respuestas DNS completas en formato wire, pero descartaron esta opción por su complejidad adicional, ya que DNSSEC, compresión de nombres y otros campos variables indicarían que sería necesario mantener múltiples representaciones o analizar completamente cada paquete en cada consulta.
Finalmente, optaron por almacenar los datos de los registros como bytes, dejando el resto de la entrada en campos estructurados.
En lugar de múltiples enum y asignaciones, almacenan los registros en un único Box<[u8]>, en orden consecutivo.
Cada registro comienza con un prefijo de dos bytes que indica su longitud, seguido del registro codificado.
Esta estrategia aporta dos beneficios principales:
- Reduce significativamente el overhead asociado a
enum, punteros y asignaciones individuales. - Los datos quedan almacenados de forma contigua en memoria, mejorando la localidad en las cachés de CPU.
A cambio, Cloudflare pierde la posibilidad de acceso aleatorio mediante índices tradicionales. Debe recorrer secuencialmente el buffer, pero considera que en entradas DNS típicas, con pocos registros, esta carga no es un problema.
Además, algunos tipos de registros, como A, AAAA, TXT o registros DNSSEC, pueden ser copiados directamente desde la caché hacia la respuesta DNS. Otros, como CNAME, NS, MX o SOA, requieren procesamiento adicional para aplicar la compresión de nombres DNS.
Cloudflare atribuye a esta reorganización una reducción adicional del 5 % en la latencia de consulta.
También utiliza un buffer temporal reutilizable para construir los registros antes de almacenarlos. Como dicho buffer ha crecido en operaciones previas, normalmente puede reutilizarse sin solicitar memoria adicional.
Según sus benchmarks, esta última modificación elevó el rendimiento de inserción de la caché en un 13 %.
De 953 a 420 bytes por entrada
El efecto acumulado de las cinco optimizaciones es mucho mayor que el de cada una de forma individual.
| Métrica | Antes | Después | Cambio |
|---|---|---|---|
| Huella neta por entrada | 953 bytes | 420 bytes | -56 % |
| Memoria asignada por entrada | 1.1 KB | 461 bytes | -58 % |
| Inserciones en caché | 625.000/s | 893.000/s | +43 % |
| Latencia de consulta | 828 ns | 670 ns | -19 % |
Estos resultados provienen de benchmarks realizados por Cloudflare, que simulan su tráfico real usando un 56 % de registros A, un 25 % de AAAA y un 19 % de TXT, con entre uno y cuatro registros por entrada.
La compañía advierte que estas pruebas no reproducen exactamente las condiciones de producción. El consumo real dependerá, entre otros factores, de la mezcla de tráfico, utilización de la caché y estado del allocator.
Por ello también analizaron sus instancias reales. En el percentil 99, el consumo residente descendió de 9,3 GB a 5,3 GB, un 43 %. En el percentil 90, pasó de 6,5 a 3,8 GB, un 42 %.
Tras completar el despliegue y estabilizar las cachés, Cloudflare estima que el conjunto de toda la infraestructura redujo su working set en aproximadamente 100 TB.
Este valor se compara con la memoria instalada en unos 130 de sus servidores Gen 13.
Pero la compañía no tiene intención de dejar esos 100 TB sin aprovechar.
Planean reinvertir parte de la capacidad liberada en ampliar las cachés sin aumentar el consumo total de memoria. Con más entradas en caché, se puede mejorar la tasa de aciertos y reducir las consultas hacia servidores DNS externos.
El caso de Big Pineapple además ofrece una lección técnica concreta: la elección de la estructura de datos adecuada puede ser tan importante como el algoritmo.
Vec, String, enum o Box no son inherentemente mejores o peores, sino que su coste depende de cómo se usen, cuánto tiempo permanezcan en memoria y cuántos objetos de millones o miles de millones existan simultáneamente.
En aplicaciones convencionales, ahorrar 64 bytes quizás no justifique una revisión del modelo de memoria. Pero, con 250.000 millones de entradas, esos 64 bytes por entrada representan terabytes en total.
Preguntas frecuentes
¿Cómo logró Cloudflare ahorrar 100 TB de RAM?
Modificando la representación en memoria de las entradas DNS, eliminando estructuras dinámicas, reduciendo redundancias, reorganizando registros y almacenando parte en un buffer binario compacto.
¿Cuántas entradas DNS mantiene Cloudflare en caché?
Más de 250.000 millones de entradas en servicios como 1.1.1.1, Gateway DNS, DNS Firewall y otros sistemas DNS de Cloudflare.
¿Las optimizaciones afectaron el rendimiento de 1.1.1.1?
Las pruebas realizadas muestran lo contrario: aumento del 43 % en inserciones y reducción del 19 % en latencia de consultas.
¿Para qué usará Cloudflare la memoria liberada?
Para ampliar sus cachés sin incrementar el uso total de RAM, mejorando la tasa de aciertos y reduciendo consultas a servidores DNS externos.
Fuente: Cloudflare
