C’è un modo molto comune di ottimizzare un sistema: prendere l’operazione più costosa e provare a eseguirla più velocemente. Poi ce n’è un altro, meno spettacolare e decisamente più difficile: chiedersi perché quell’operazione debba essere eseguita per intero. La seconda strada è interessante finché non arriva la domanda che conta davvero: come dimostri che, facendo meno lavoro, il risultato resta corretto?
È il punto centrale del lavoro pubblicato da Cloudflare il 2 novembre 2026 sul proprio DNS Zone Builder. I numeri attirano subito l’attenzione: picco di memoria ridotto dell’85%, meno ricostruzioni complete e tempo mediano di completamento della build sceso da circa 7,7 a 3,3 secondi. Ma fermarsi a quei numeri significherebbe perdere la parte più utile per chi sviluppa software: il metodo con cui si decide che cosa è lecito non ricalcolare.
Il problema non erano i 700 eventi al secondo
Nel 2022 il Zone Builder riceveva circa 250 modifiche ai record DNS al secondo. Oggi, secondo Cloudflare, ne riceve circa 700, oltre a un centinaio di altri eventi al secondo. Le zone più grandi superano i 20 milioni di record. È facile concludere che il problema sia il volume di messaggi. Non lo è, almeno non da solo.
Una modifica a un singolo record può richiedere un intervento minuscolo. Un cambiamento nelle impostazioni di zona, invece, in passato poteva far ricostruire l’intera zona: leggere tutti i record, trasformarli nel formato servito all’edge, confrontarli con lo stato in Quicksilver e scrivere le differenze. Anche quando alla fine cambia pochissimo, il costo della lettura e della trasformazione rimane. Il sistema può scrivere soltanto poche chiavi, ma aver già speso CPU e memoria per milioni di record.
La pipeline ha passaggi precisi: le modifiche vengono registrate nel database, gli eventi attraversano Kafka e il DNS Kafka Aggregator, il Zone Builder costruisce le chiavi da pubblicare e Quicksilver le distribuisce nella rete. Il punto importante è che la build e la distribuzione globale non sono la stessa misura. Torneremo su questa distinzione, perché cambia completamente il modo di leggere i benchmark.
Un planner che deve provare la correttezza, non indovinare
Cloudflare ha reso più informativi gli eventi sulle impostazioni: quali campi sono cambiati, e quando disponibili i valori precedenti e successivi. Da queste informazioni il planner sceglie il tipo di lavoro più piccolo che possa produrre lo stesso stato di una ricostruzione completa.
- Resources only: ricalcola soltanto i nomi DNS coinvolti, senza toccare i metadati condivisi.
- Resources and metadata: aggiorna nomi specifici e metadati, per esempio quando entrano in gioco wildcard o nameserver.
- Apex and metadata: ricalcola l’apice della zona e i metadati; alcune impostazioni come Universal SSL possono influire sui record CAA.
- Purge: rimuove lo stato di una zona che non deve più essere pubblicata.
- Full zone: ricostruisce tutto quando non è possibile dimostrare che un piano ridotto sia sufficiente.
Questa classificazione è meno banale di quanto sembri. Un evento che aggiorna soltanto un timestamp potrebbe essere un’operazione amministrativa innocua oppure il segnale di una modifica altrove. Se non si riesce a distinguerli, il planner non deve inventarsi una certezza. Deve scegliere il percorso conservativo.
La vera ottimizzazione non è saltare passaggi. È sapere quali passaggi puoi saltare senza cambiare il risultato.
La regola verificata da Cloudflare è l’equivalenza byte per byte delle chiavi che un piano mirato deve produrre rispetto alla build completa. È un’invariante concreta, non una generica promessa di comportamento equivalente. E costringe a considerare anche le cancellazioni: quando un record cambia nome o scompare, il sistema deve rimuovere le vecchie chiavi, non limitarsi a scrivere quelle nuove.
Lo stato cambia mentre il messaggio aspetta
In un sistema a eventi c’è una trappola ricorrente: un messaggio descrive il passato, ma l’operazione viene eseguita nel presente. Tra i due momenti il database può essere cambiato, una zona può essere stata disabilitata su una rete oppure può essere cambiato l’insieme di zone che condividono lo stesso nome.
Per questo Cloudflare separa il piano iniziale dalla verifica immediatamente precedente alla scrittura. Il Zone Builder rilegge uno snapshot aggiornato delle impostazioni, della pubblicazione sulla rete di destinazione e delle zone con lo stesso nome. Un piano mirato può diventare full, trasformarsi in purge o essere annullato se lo stato corrente lo richiede.
C’è poi il problema della replica. Kafka e la replica del database avanzano in modo indipendente: l’evento può arrivare prima che la modifica sia visibile sulla replica di lettura. Un buffer temporale copre il normale ritardo, ma non basta affidarsi al tempo. Il controllo finale deve rifiutare una replica ancora indietro. È la differenza tra sperare che i dati siano aggiornati e verificarlo.
Uno scheduler unico, ma nessun messaggio perso
Prima esistevano scheduler separati per il lavoro sui record e per le build complete. Ognuno aggregava i propri eventi, ma i due mondi non potevano fondersi. Il nuovo scheduler unifica il lavoro per zona: una modifica a un record A e una wildcard possono diventare un’unica build che comprende i due nomi e i metadati. Se un evento richiede la zona completa, il piano combinato si allarga. Se serve una purge, quella prevale.
Il dettaglio architetturale è che il lavoro da fare e i messaggi Kafka da confermare restano due insiemi distinti. Accorpare le operazioni non autorizza ad accorpare con leggerezza gli acknowledgment. Una partizione Kafka avanza con offset contigui: se il messaggio 2 non è terminato, non puoi confermare definitivamente il 3 e il 4 solo perché hanno finito prima. Dopo un crash potrebbero essere riprodotti. Meglio un lavoro ripetuto che una modifica persa.
È un principio che ritroviamo anche nei sistemi applicativi più ordinari. Una coda di job non è affidabile perché il worker esegue velocemente, ma perché retry, idempotenza e commit rispettano lo stato reale. Il tema è vicino a quello affrontato nell’articolo su Symfony Messenger, inbox e redelivery: il messaggio può tornare, mentre gli effetti devono restare coerenti. Non sono architetture identiche, ma condividono il problema di distinguere elaborazione e conferma.
Le zone gigantesche mettono in crisi anche il fallback
Dire “quando non sei sicuro, rifai tutto” sembra una strategia inattaccabile. Non lo è quando una zona non entra nemmeno in memoria. Cloudflare esplicita un’eccezione: oltre una soglia di record, non forza il full build perché potrebbe non terminare e bloccare gli altri eventi della stessa partizione. Ricalcola invece apex, metadati e nomi identificati dagli eventi, affidandosi anche a vincoli operativi e, per casi rari, a interventi mirati.
Questo non cancella il rischio: lo delimita. La scelta conservativa non è sempre l’operazione teoricamente più completa, ma quella che mantiene il sistema operativo senza fingere che una procedura impossibile sia una garanzia. È un trade-off dichiarato, non una scorciatoia nascosta dietro il nome “ottimizzazione”.
Come si testa una riduzione di lavoro senza auto-convincersi
I test unitari verificano che i piani mirati producano le stesse chiavi di una build completa a parità di stato, fissando anche i valori dipendenti dal tempo. Ma in produzione esistono combinazioni di configurazioni che una suite non può enumerare tutte. Cloudflare ha quindi affiancato una pipeline mirror: consuma gli eventi reali e legge i dati reali, ma scrive in un ambiente Quicksilver separato che non serve traffico.
Un comparatore controlla un campione del 20% delle zone per chiavi mancanti, in eccesso o differenti. Un disallineamento momentaneo non dimostra automaticamente un bug: le due pipeline possono aver elaborato lo stesso cambiamento in istanti diversi. Si osservano differenze nuove che persistono dopo il riallineamento. Anche il rollout è stato progressivo, usando l’hash del nome della zona e non dell’ID: zone che condividono il nome devono rimanere sullo stesso scheduler per non contendersi metadati comuni.
Qui il metodo è trasferibile: definire l’output canonico, confrontarlo in shadow mode, distinguere divergenze temporanee da regressioni stabili, distribuire per una chiave che rispetti la proprietà condivisa dei dati. Non basta mettere un feature flag davanti a un nuovo algoritmo.
I numeri sono utili, purché si misuri la cosa giusta
Nel campione di 24 ore riportato da Cloudflare, l’86,81% delle build era resources-only, il 2,54% resources+metadata, il 2,30% apex+metadata e l’1,30% purge. In totale il 92,95% non richiedeva una ricostruzione completa. Questo non significa che il numero di full build sia diminuito del 92,95%: rispetto al comportamento precedente la riduzione stimata delle full build è di circa il 40%. Sono due denominatori diversi.
Nello stesso confronto interno il working set medio è sceso da 49 a 7 GiB, e il picco da 79 a 12 GiB. Il confronto side-by-side fra vecchio e nuovo scheduler ha mostrato un picco p99 del ritardo di completamento ridotto da 14,6 a 1,21 minuti. Con più capacità libera, Cloudflare ha poi potuto ridurre alcuni intervalli di attesa e il buffer per le repliche, portando il ritardo mediano di completamento della build da circa 7,7 a 3,3 secondi.
Non è il tempo necessario a un record DNS per essere visibile ovunque nel mondo. La metrica termina quando il Zone Builder ha scritto su Quicksilver; la distribuzione successiva non è compresa. Inoltre il confronto dei picchi p99 e la misura della mediana appartengono a osservazioni diverse del rollout. Confonderle produce una storia più semplice da raccontare, ma tecnicamente falsa.
La lezione per chi sviluppa software
Da questa vicenda escono tre domande che hanno senso ben oltre il DNS. Qual è l’unità minima di lavoro che modifica davvero l’output? Quale invariante permette di dimostrare che un aggiornamento parziale è equivalente a uno completo? E quale percorso resta sicuro quando l’evento è ambiguo, la replica è in ritardo o un job non termina?
In molti progetti il primo impulso è aumentare worker, memoria, code o cache. A volte è necessario. Ma se un evento minuscolo innesca una ricostruzione globale, stiamo soltanto finanziando un errore di granularità. La parte impegnativa non è scrivere il nuovo scheduler: è progettare il confine entro cui il nuovo scheduler può fare meno senza introdurre stato stantio, cancellazioni mancate o conferme premature.
Cloudflare ha pubblicato numeri importanti. Il contributo più interessante, però, è un criterio di progettazione verificabile: ridurre il lavoro solo dopo aver definito ciò che non deve cambiare. È molto meno vendibile di un benchmark. Ed è proprio per questo che vale la pena studiarlo.
Domande frequenti
Che cosa sono i targeted zone builds di Cloudflare?
Sono piani di ricostruzione mirata delle chiavi DNS: in base all’evento il Zone Builder aggiorna solo record e metadati necessari, oppure usa un full build quando non può dimostrare la sicurezza del piano ridotto.
Cloudflare ha ridotto del 92,95% le ricostruzioni complete?
No. Nel campione di 24 ore il 92,95% delle build ha evitato la ricostruzione completa; rispetto al vecchio comportamento Cloudflare stima una riduzione di circa il 40% del numero di full build. Le due percentuali hanno basi diverse.
Il passaggio da 7,7 a 3,3 secondi indica la propagazione DNS globale?
No. Misura il tempo tra la modifica DNS e il completamento della scrittura del Zone Builder in Quicksilver. Non comprende la successiva distribuzione globale di Quicksilver.
Perché il nuovo scheduler non può confermare subito tutti i messaggi Kafka elaborati?
Kafka conferma gli offset in modo contiguo per partizione. Se un messaggio precedente non è concluso, avanzare oltre potrebbe perdere una modifica dopo un riavvio; il sistema preferisce consentire il replay.
Come ha verificato Cloudflare che i build parziali non cambiassero il risultato?
Con test di equivalenza byte per byte rispetto ai full build, un Zone Builder mirror non serving, confronto di un campione del 20% delle zone e rollout progressivo basato sull’hash del nome della zona.
