Una zona DNS de Cloudflare puede tener más de 20 millones de registros, y hasta hace poco bastaba con activar o desactivar Universal SSL para que su Zone Builder la reconstruyera entera. Tras cambiar eso, el equipo de DNS ha bajado la memoria del servicio de 49 a 7 GiB de media y ha reducido a la mitad lo que tarda un cambio en llegar a su almacén de configuración, según cuenta Alex Fattouche en el blog de Cloudflare el 2 de noviembre de 2026.
El problema: más eventos y zonas cada vez más grandes
El Zone Builder convierte el estado de la base de datos en las claves que leen los servidores DNS autoritativos y las escribe en Quicksilver, el almacén clave-valor distribuido de Cloudflare. En 2022 recibía unos 250 cambios de registros por segundo; ahora son unos 700, más otros 100 eventos como cambios de ajustes de zona.
El volumen no era lo grave. Lo grave era el tipo de trabajo. En 2022 ya habían conseguido que cambiar un registro solo reconstruyera ese registro (150 veces más rápido de media que una build completa). Pero los cambios de ajustes de zona seguían disparando una build completa: leer todos los registros, codificarlos, compararlos con Quicksilver y tener la zona entera en memoria. En las zonas más grandes, eso ni siquiera cabe en memoria.
La solución: un planificador que solo reduce trabajo cuando puede demostrarlo
La pieza central es un planificador que elige entre cinco tipos de build: solo nombres concretos, nombres más metadatos compartidos, ápex más metadatos, purga de la zona o zona completa. La regla que lo gobierna es muy sencilla: cada clave que escribe una build parcial tiene que ser idéntica, byte a byte, a la que escribiría una build completa. Si no se puede demostrar, se hace la completa. Un evento ambiguo, sin detalle o desconocido nunca se traduce en menos trabajo.
Para que eso fuera posible tuvieron que resolver varias cosas a la vez:
- Eventos que dicen qué cambió. El productor ahora incluye los campos y ajustes modificados, con el valor anterior y el nuevo cuando los hay. Algunas funciones de base de datos solo actualizan una marca de tiempo; esos eventos siguen provocando una build completa hasta que identifiquen quién los genera.
- Planificar dos veces. El evento produce un plan conservador, y justo antes de ejecutar se relee un snapshot fresco desde réplicas de lectura. El plan puede crecer a build completa, convertirse en purga o descartarse. Como Kafka y la replicación avanzan por separado, el agregador retrasa los eventos y la base de datos rechaza la lectura si la réplica va atrasada.
- Un único scheduler. Antes, el trabajo por registro y el de zona completa iban por schedulers distintos que no podían combinarse. Ahora uno solo fusiona lo pendiente de cada zona, y la fusión solo puede añadir trabajo: si un evento pide la zona entera, la build combinada es completa, y una purga se impone a cualquier reconstrucción.
- No perder mensajes. El scheduler guarda por separado el trabajo DNS y los mensajes de Kafka pendientes de confirmar. Con soft commit, una build puede terminar fuera de orden, pero el offset solo avanza cuando han terminado todos los mensajes anteriores. Prefieren repetir trabajo tras un reinicio antes que perder un cambio.
Hay una excepción deliberada: por encima de cierto número de registros, el Zone Builder nunca escala a build completa, porque no terminaría y bloquearía toda su partición de Kafka mientras reintenta. En esos casos reconstruye el ápex, los metadatos y los nombres afectados, y los casos raros se arreglan a mano.
Cómo lo validaron antes de soltarlo
Lo más trasladable del caso está aquí. Además de tests que comparan byte a byte una build parcial con una completa desde el mismo estado, durante el despliegue ejecutaron una build completa junto a cada build parcial. Y cada release pasa por un Zone Builder espejo que consume el mismo stream de Kafka de producción y lee la misma base de datos, pero escribe en un Quicksilver aparte sin tráfico. Un comparador revisa el 20 % de las zonas; la captura que publican muestra un 0,31 % de diferencias sobre 234.313 zonas, casi todas por desfase temporal entre los dos entornos.
El despliegue se hizo por hash del nombre de la zona, no de su ID: todas las zonas que comparten nombre (y por tanto la misma clave de metadatos) caían en el mismo scheduler, y así dos schedulers nunca escribían la misma clave. Primero zonas gratuitas, después de pago.
Resultados
| Métrica | Antes | Después |
|---|---|---|
| Memoria media del Zone Builder | 49 GiB | 7 GiB |
| Pico de memoria | 79 GiB | 12 GiB |
| Peor pico de p99 de retraso (24 h) | 14,6 min | 1,21 min |
| Mediana de retraso hasta Quicksilver | ~7,7 s | ~3,3 s |
| Consumo de Kafka | ráfagas de hasta 1.550 msg/s | sigue a la producción (600–800 msg/s) |
En 24 horas, el 92,95 % de las builds evitó reconstruir la zona completa; las builds completas bajaron cerca de un 40 % y las que quedan duran 0,35 s de media, porque afectan sobre todo a zonas nuevas y pequeñas. La mediana se redujo a la mitad porque, con builds más baratas, pudieron acortar dos esperas de seguridad: el intervalo mínimo entre reconstrucciones de una misma zona y el tiempo que el agregador retiene cada evento para que las réplicas se pongan al día.
Qué me llevo
La primera lección es el contrato de equivalencia. Optimizar un proceso que reconstruye estado (un controlador, un generador de configuración, una caché) es arriesgado, porque el fallo típico no es un error, sino datos viejos que nadie ve. Definir que la versión incremental debe producir exactamente lo mismo que la completa, y caer a la completa ante cualquier duda, convierte la optimización en algo verificable.
La segunda es el entorno espejo con tráfico real. Los tests no cubren todas las combinaciones de clientes; un consumidor paralelo del mismo stream que escribe en un destino aislado, con un comparador por muestreo, sí.
La tercera es sobre medir. Su histograma tenía cubos en 1, 5, 10 y 30 segundos y el p99 salía cerca de 30 s; con un histograma nativo de cubos finos, el p99 real ronda los 12 s y el p90, unos 5,5 s. Si tus SLO de latencia dependen de percentiles calculados sobre cubos gruesos, probablemente estás leyendo valores inflados.
Lo que no es trasladable
Quicksilver y el Zone Builder son internos, y los umbrales (zonas de decenas de millones de registros, cientos de eventos por segundo) quedan lejos de la mayoría de equipos. Lo que sí se puede copiar son los patrones: planificar con lo que dice el evento, verificar contra el estado fresco antes de escribir y no confirmar un offset hasta que todo lo anterior esté hecho.
Fuentes
- How we halved DNS build delay and cut memory use by 85%, Cloudflare Blog, 2 de noviembre de 2026.
- How we improved DNS record build speed by more than 4,000x, Cloudflare Blog, 25 de mayo de 2022.