Cloudflare ha reducido en torno a 100 TB el consumo agregado de memoria de la infraestructura que ejecuta su plataforma DNS Big Pineapple después de modificar cómo representa y almacena en RAM las entradas de caché. El trabajo no se ha basado en añadir servidores, sino en cinco cambios sucesivos sobre estructuras de datos escritas en Rust que han reducido un 56 % la huella de memoria por entrada y, al mismo tiempo, han mejorado el rendimiento de la caché.
Las claves de la optimización de Cloudflare en 30 segundos
- Big Pineapple mantiene más de 250.000 millones de entradas DNS simultáneamente para servicios como 1.1.1.1, Gateway DNS y DNS Firewall.
- Cloudflare redujo la huella media de cada entrada de 953 a 420 bytes, un 56 %.
- El ahorro agregado ronda los 100 TB de memoria, equivalente a la RAM de unos 130 servidores Gen 13 de la compañía.
- Las inserciones aumentaron un 43 % y la latencia de consulta bajó un 19 %.
- Buena parte de la mejora procede de reducir asignaciones, eliminar datos redundantes y almacenar registros DNS de forma más compacta.
El caso resulta especialmente interesante para administradores de sistemas y desarrolladores porque demuestra hasta qué punto unas pocas decenas de bytes dejan de ser insignificantes cuando una aplicación trabaja a gran escala. Big Pineapple mantiene más de 250.000 millones de elementos en caché en un momento dado. Con ese volumen, un solo byte desperdiciado por entrada supone más de 250 GB de memoria en toda la infraestructura.
Cloudflare comenzó a desplegar estas modificaciones el 18 de mayo de 2026 y completó su extensión a todos los servicios el 6 de julio. El resultado se midió tanto mediante benchmarks como observando el consumo residente de memoria de las instancias reales en producción.
De Vec y String a estructuras que ocupan exactamente lo necesario
Una entrada de caché DNS contiene bastante más información que 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ó de una característica habitual de Rust.
Un Vec<T> necesita conservar tres datos: un puntero hacia los elementos, su longitud actual y su capacidad. Esa capacidad adicional resulta imprescindible mientras una colección puede seguir creciendo.
El problema es que una respuesta DNS almacenada en la caché de Cloudflare ya no cambia después de insertarse.
Mantener capacidad para futuros elementos carecía por tanto de utilidad.
Cloudflare sustituyó varios Vec<T> por Box<[T]>, una estructura de tamaño fijo que no necesita almacenar capacidad adicional. Aplicó una idea parecida a cadenas de texto, reemplazando determinados String por Box<str>.
Cada entrada mantenía ocho campos de estos tipos. Eliminar ocho bytes por campo permitió ahorrar 64 bytes por entrada, además del espacio que los vectores podían haber reservado y no utilizar.
A escala de toda la plataforma, únicamente este cambio representa más de 15 TB de memoria según los cálculos de Cloudflare.
Es un buen ejemplo de cómo debe analizarse el consumo en servicios de gran escala. Una estructura perfectamente razonable para una aplicación convencional puede resultar demasiado cara cuando existen cientos de miles de millones de instancias de ella.
Menos listas y menos punteros
Cloudflare también revisó cómo almacenaba las tres secciones principales de una respuesta DNS: respuesta, autoridad e información adicional.
Inicialmente cada sección tenía su propia lista.
La nueva representación utiliza una única colección de registros y pequeños desplazamientos para conocer dónde comienza cada sección.
Como el número de registros puede representarse mediante valores u16, cada desplazamiento necesita únicamente dos bytes.
La compañía calcula que esta modificación permite ahorrar 28 bytes por entrada al eliminar dos listas independientes con sus respectivos punteros y longitudes.
También aparecen detalles propios de la programación de bajo nivel. Rust introduce padding para mantener correctamente alineados determinados campos dentro de una estructura. Por eso eliminar o reorganizar campos pequeños puede producir un ahorro superior al tamaño aparente de esos datos.
Cloudflare aprovechó esta circunstancia agrupando también varios valores booleanos mediante bitflags.
Eliminar información repetida y reducir el coste de los enum de Rust
Otro de los cambios se centró en el propietario de cada registro DNS.
Una consulta para un registro A de un dominio suele devolver registros cuyo propietario coincide exactamente con el dominio solicitado. Guardar repetidamente ese nombre dentro de cada registro supone mantener información que ya está disponible en la clave de la caché.
Cloudflare decidió no almacenarlo cuando ambos valores coinciden.
Solo conserva explícitamente el propietario cuando realmente es diferente, algo que puede ocurrir, por ejemplo, después de seguir un registro CNAME.
Cuando posteriormente se reconstruye la respuesta, Big Pineapple recupera el dominio original desde la propia clave de caché.
El resultado es menos memoria utilizada y menos asignaciones en el heap para el caso más frecuente.
La siguiente optimización resulta particularmente interesante desde el punto de vista de Rust.
Un enum puede contener variantes con tamaños muy diferentes, pero la estructura tiene que reservar espacio suficiente para alojar su variante de mayor tamaño.
Cloudflare tenía una representación similar a esta:
pub enum RecordData {
A(Ipv4Addr),
Aaaa(Ipv6Addr),
Txt(Txt),
Naptr(Naptr),
Svcb(Svcb),
}
El problema era NAPTR.
Su estructura podía necesitar unos 136 bytes y hacía que el enum, sumando identificador de variante y alineación, llegase a 144 bytes.
Sin embargo, un registro IPv4 A solo necesita cuatro bytes de datos y uno AAAA utiliza 16.
La diferencia importa porque los registros A y AAAA representan más del 80 % del tráfico utilizado por Cloudflare en sus pruebas.
Eso significaba reservar más de 120 bytes innecesarios para muchos de los registros más habituales.
Box resolvió parte del problema, pero creó otro
Una primera solución consistió en mantener directamente dentro del enum los registros pequeños y colocar las variantes grandes en memoria dinámica mediante Box.
El tamaño de la estructura principal cayó considerablemente.
Pero apareció un nuevo coste.
Cada Box requiere una asignación independiente en el heap. Big Pineapple utiliza jemalloc, que agrupa las asignaciones en diferentes clases de tamaño, por lo que una petición puede acabar ocupando ligeramente más memoria de la solicitada.
El problema más interesante estaba, sin embargo, en la CPU.
Al distribuir los datos por diferentes zonas del heap, el procesador tiene que seguir punteros para recuperar cada registro. Esos datos pueden encontrarse lejos unos de otros y provocar más accesos a diferentes líneas de caché.
Es decir, ahorrar memoria podía terminar perjudicando la localidad de los datos.
Cloudflare continuó buscando otra representación.
Guardar parte de DNS casi como viaja por la red mejoró memoria y velocidad
La solución final consistió en acercarse al propio formato binario utilizado por DNS.
La compañía valoró almacenar directamente las respuestas DNS completas en formato wire, pero descartó hacerlo de forma general porque habría introducido otras complicaciones. DNSSEC, la compresión de nombres y determinados campos que cambian según el cliente obligarían a mantener varias representaciones o a volver a analizar paquetes completos en cada consulta.
El punto intermedio fue almacenar los datos de los registros como bytes, manteniendo el resto de la entrada como campos estructurados.
En vez de disponer de numerosos enum y asignaciones individuales, los registros se guardan consecutivamente dentro de un único Box<[u8]>.
Cada elemento contiene un prefijo de dos bytes indicando su longitud seguido del registro codificado.
Esta decisión aporta dos ventajas.
La primera es evidente: desaparece buena parte del overhead asociado con los enum, punteros y asignaciones independientes.
La segunda afecta al procesador: los datos quedan almacenados de manera contigua, mejorando la localidad en las cachés de CPU.
Cloudflare pierde a cambio la posibilidad de acceder aleatoriamente a cualquier registro mediante un índice tradicional. Tiene que recorrer secuencialmente el buffer.
En este caso la compañía considera asumible el coste porque una entrada DNS normalmente contiene pocos registros.
Además, determinados tipos pueden copiarse casi directamente desde la caché hacia la respuesta DNS.
Esto ocurre con registros A, AAAA, TXT y diferentes registros DNSSEC. Otros que contienen nombres de dominio, como CNAME, NS, MX o SOA, todavía requieren procesamiento para aplicar correctamente la compresión de nombres DNS.
Cloudflare atribuye a esta reorganización por sí sola 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 ese espacio ya ha crecido durante operaciones anteriores, normalmente puede reutilizarse sin solicitar continuamente nueva memoria.
Según sus benchmarks, esta última modificación incrementó por sí sola el rendimiento de inserción de la caché un 13 %.
De 953 a 420 bytes por entrada
El efecto acumulado de las cinco optimizaciones es mucho mayor que el de cualquiera de ellas por separado.
| 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 % |
Los resultados proceden de los benchmarks de Cloudflare, que intentan aproximarse a su tráfico real utilizando un 56 % de registros A, un 25 % de AAAA y un 19 % de TXT, con entre uno y cuatro registros por entrada.
La propia compañía advierte de que estas pruebas no reproducen exactamente la producción. El consumo real depende, entre otros factores, de la mezcla de tráfico, la ocupación de la caché, el estado del allocator y otra memoria utilizada por el proceso.
Por eso también midió sus instancias reales.
En el percentil 99, el consumo residente cayó de 9,3 GB a 5,3 GB, un 43 %. En el percentil 90 pasó de 6,5 a 3,8 GB, un 42 %.
Una vez completado el despliegue y estabilizadas las cachés, Cloudflare calcula que el working set agregado de toda la infraestructura se había reducido aproximadamente 100 TB.
La compañía compara esa cantidad con la memoria instalada en aproximadamente 130 de sus servidores Gen 13.
Pero no pretende dejar necesariamente esos 100 TB sin utilizar.
Cloudflare planea reinvertir parte de la capacidad liberada en ampliar sus cachés sin aumentar el consumo total de memoria. Una caché capaz de conservar más entradas puede mejorar su tasa de aciertos y reducir las consultas que necesitan enviarse hacia servidores DNS externos.
El caso de Big Pineapple deja además una enseñanza técnica bastante concreta para servicios de gran escala: elegir la estructura de datos correcta puede importar tanto como elegir el algoritmo.
Vec, String, enum o Box no son mejores o peores por sí mismos. Su coste depende de cómo se utilizan, cuánto tiempo permanecen en memoria y cuántos millones o miles de millones de objetos acaban existiendo simultáneamente.
En una aplicación convencional, ahorrar 64 bytes puede no justificar una revisión completa del modelo de memoria. Con 250.000 millones de entradas, esos mismos 64 bytes se convierten en terabytes.
Preguntas frecuentes
¿Cómo ha conseguido Cloudflare ahorrar 100 TB de RAM?
Cloudflare modificó la representación en memoria de las entradas de su caché DNS, reduciendo estructuras dinámicas, eliminando información redundante, reorganizando registros y almacenando parte de ellos en un buffer binario compacto.
¿Cuántas entradas DNS mantiene Cloudflare en caché?
Big Pineapple mantiene más de 250.000 millones de entradas simultáneamente entre servicios como 1.1.1.1, Gateway DNS, DNS Firewall y otros sistemas DNS de Cloudflare.
¿Las optimizaciones redujeron el rendimiento de 1.1.1.1?
Según los benchmarks publicados por Cloudflare ocurrió lo contrario. El rendimiento de inserción aumentó un 43 % y la latencia de consulta bajó un 19 %.
¿Para qué utilizará Cloudflare la memoria liberada?
La compañía prevé emplear parte de esa capacidad para aumentar el tamaño de sus cachés sin incrementar el consumo total de RAM, con el objetivo de elevar la tasa de aciertos y reducir consultas hacia servidores upstream.
Fuente: Cloudflare