Час поширення DNS: 3 секунди Cloudflare проти вашого TTL
Коротко (перевірено 2026-11-03): Cloudflare цього тижня написав, що вдвічі скоротив час від зміни DNS-запису до моменту, коли система збірки його записала: медіана впала з приблизно 7,7 до приблизно 3,3 секунди, а пам'ять для цієї роботи зменшилася на 85%. Це хороша інженерія, але це не та затримка, яку ви бачите, коли переносите сайт на новий сервер. Ваше очікування визначають числа, які ви обираєте або принаймні можете прочитати: TTL запису, значення негативного кешу в SOA і, якщо ви міняєте сервери імен, дводенний TTL у реєстрі .com. Ми написали невеликий скрипт, який читає їх усі для будь-якої зони, запустили його на нашій зоні й на зоні Cloudflare і склали з результату план перемикання.
Джерело. "We halved DNS build delay and cut memory use by 85%" (блог Cloudflare, опубліковано 2026-11-02), обговорення на Hacker News, 173 бали станом на 2026-11-03. Їхні цифри наведено так, як їх опубліковано; відповіді DNS нижче ми запитали самі.
Що змінив Cloudflare
Зміна через API або панель потрапляє в базу даних, потім у Kafka, потім у Zone Builder, який перетворює зону на ключі й записує лише різницю в Quicksilver, сховище ключ-значення, що доставляє її в кожен дата-центр Cloudflare. "Затримка збірки" - це лише перша частина: від зміни до завершення запису в Zone Builder. Розповсюдження сюди не входить. Кількість змін записів зросла з приблизно 250 на секунду у 2022 році до приблизно 700, а деякі зони мають понад 20 мільйонів записів, тож перебудовувати всю зону заради одного запису стало дорого. Новий планувальник обирає найменшу безпечну збірку; у 24-годинній вибірці 92,95% збірок обійшлися без повної перебудови.
| Показник (Cloudflare, опубліковано 2026-11-02) | До | Після |
|---|---|---|
| Медіана затримки збірки | близько 7,7 с | близько 3,3 с |
| Найбільший сплеск p99 | 14,6 хв | 1,21 хв |
| Середня робоча пам'ять | 49 GiB | 7 GiB |
| Частка повних збірок зони | 11,88% | 7,04% |
На новій, точнішій гістограмі p99 здебільшого лежить між 10 і 14 секундами. Для клієнта корисний саме хвіст: зміна, яка в погану хвилину тривала чверть години, тепер триває близько хвилини.
Шари, на які ви насправді чекаєте
Резолвер відвідувача не питає Cloudflare чи іншого провайдера при кожному запиті. Він зберігає відповідь на час TTL запису й лише потім питає знову. Тож секунди провайдера додаються до хвилин або днів, про які вирішують в іншому місці:
| Шар | Хто задає | Що ми побачили або знайшли |
|---|---|---|
| Збірка у провайдера | DNS-провайдер | Cloudflare медіана ~3,3 с, p99 10-14 с |
| TTL запису | ви | 300 с www.cloudflare.com, 1800 с dcxv.com |
| Негативний кеш (імені не було) | мінімум SOA, RFC 2308 | 300 с cloudflare.com, 3600 с dcxv.com |
| Делегування серверів імен | реєстр .com | 172800 с (2 дні) для обох зон |
| Serve-stale під час збою | резолвер, RFC 8767 | рекомендовано 1-3 дні, з TTL 30 с |
Рядки з TTL узято з нашого запуску нижче; рядок serve-stale - це рекомендація RFC, а не вимірювання. Документація Cloudflare каже, що проксійований запис має фіксований Auto = 300 с, а запис лише DNS можна задати від 60 с (30 с на Enterprise) до 1 дня (документація Cloudflare про TTL, перевірено 2026-11-03).
Перевірте зону самі: dnscut.js
Скрипт питає сервер TLD про TTL делегування, кожен авторитетний сервер - про серійний номер SOA і сам запис, а три публічні резолвери - що вони тримають зараз і як довго ще триматимуть. Потрібні лише вбудований у Bun node:dns і dig для одного запиту без рекурсії. Збережіть його як dnscut.js:
// dnscut.js - how long until a DNS change is visible everywhere
// usage: bun dnscut.js <zone> [name] e.g. bun dnscut.js example.com www.example.com
import { Resolver } from 'node:dns/promises'
const zone = process.argv[2] ?? 'example.com'
const name = process.argv[3] ?? zone
const PUBLIC = { Cloudflare: '1.1.1.1', Google: '8.8.8.8', Quad9: '9.9.9.9' }
const sys = new Resolver()
const at = ip => {
const r = new Resolver({ timeout: 3000, tries: 2 })
r.setServers([ip])
return r
}
// 1. parent (TLD) delegation: how long resolvers may keep the old name servers
const tld = zone.split('.').pop()
const tldNs = (await sys.resolveNs(tld)).sort()[0]
const tldIp = (await sys.resolve4(tldNs))[0]
const dig = Bun.spawnSync(['dig', '+norec', '+noall', '+authority', 'NS', zone, '@' + tldIp])
const deleg = dig.stdout.toString().split('\n').find(l => /\sNS\s/.test(l))
console.log(`Zone ${zone}, name ${name}`)
console.log(`Delegation at .${tld} (${tldNs}): NS TTL ${deleg?.split(/\s+/)[1] ?? '?'} s`)
// 2. every authoritative server: same SOA serial, same answer?
const serials = new Set()
let ttl = 0
let neg = 0
for (const n of (await sys.resolveNs(zone)).sort()) {
try {
const r = at((await sys.resolve4(n))[0])
const soa = await r.resolveSoa(zone)
const a = await r.resolve4(name, { ttl: true })
serials.add(soa.serial)
ttl = Math.max(ttl, ...a.map(x => x.ttl))
neg = soa.minttl // RFC 2308: negative answers are cached for min(SOA TTL, SOA MINIMUM)
console.log(` ${n.padEnd(24)} serial ${soa.serial} A ${a.map(x => x.address).join(',')} TTL ${a[0].ttl}`)
} catch (e) {
console.log(` ${n.padEnd(24)} ERROR ${e.code}`)
}
}
console.log(serials.size === 1 ? 'Authoritative servers agree.' : `Authoritative servers DISAGREE: ${[...serials].join(' / ')}`)
// 3. public resolvers: what they hold now and how long they may keep it
let left = 0
for (const [label, ip] of Object.entries(PUBLIC)) {
try {
const a = await at(ip).resolve4(name, { ttl: true })
left = Math.max(left, ...a.map(x => x.ttl))
console.log(` ${label.padEnd(10)} ${a.map(x => x.address).join(',')} TTL left ${a[0].ttl} s`)
} catch (e) {
console.log(` ${label.padEnd(10)} ERROR ${e.code}`)
}
}
console.log(`Record TTL ${ttl} s: after a change, caches may serve the old answer for up to ${ttl} s (these three: ${left} s).`)
console.log(`SOA minimum ${neg} s: a resolver that saw NXDOMAIN for a new name may keep it that long.`)
bun dnscut.js dcxv.com
bun dnscut.js cloudflare.com www.cloudflare.com
Результат, запущено на хмарному сервері DCXV з Bun 1.4.4 і dig 9.20.24 2026-11-03 (спочатку наша зона, потім зона Cloudflare):
Zone dcxv.com, name dcxv.com
Delegation at .com (a.gtld-servers.net): NS TTL 172800 s
ns1.dcxv.com serial 2025120630 A 217.28.140.182 TTL 1800
ns2.dcxv.com serial 2025120630 A 217.28.140.182 TTL 1800
ns3.dcxv.com serial 2025120630 A 217.28.140.182 TTL 1800
ns4.dcxv.com serial 2025120630 A 217.28.140.182 TTL 1800
ns5.dcxv.com serial 2025120630 A 217.28.140.182 TTL 1800
ns6.dcxv.com serial 2025120630 A 217.28.140.182 TTL 1800
Authoritative servers agree.
Cloudflare 217.28.140.182 TTL left 1800 s
Google 217.28.140.182 TTL left 1800 s
Quad9 217.28.140.182 TTL left 1800 s
Record TTL 1800 s: after a change, caches may serve the old answer for up to 1800 s (these three: 1800 s).
SOA minimum 3600 s: a resolver that saw NXDOMAIN for a new name may keep it that long.
Zone cloudflare.com, name www.cloudflare.com
Delegation at .com (a.gtld-servers.net): NS TTL 172800 s
ns3.cloudflare.com serial 2418847198 A 104.16.124.96,104.16.123.96 TTL 300
ns4.cloudflare.com serial 2418847198 A 104.16.123.96,104.16.124.96 TTL 300
ns5.cloudflare.com serial 2418847198 A 104.16.124.96,104.16.123.96 TTL 300
ns6.cloudflare.com serial 2418847198 A 104.16.124.96,104.16.123.96 TTL 300
ns7.cloudflare.com serial 2418847198 A 104.16.124.96,104.16.123.96 TTL 300
Authoritative servers agree.
Cloudflare 104.16.124.96,104.16.123.96 TTL left 242 s
Google 104.16.124.96,104.16.123.96 TTL left 300 s
Quad9 104.16.123.96,104.16.124.96 TTL left 181 s
Record TTL 300 s: after a change, caches may serve the old answer for up to 300 s (these three: 300 s).
SOA minimum 300 s: a resolver that saw NXDOMAIN for a new name may keep it that long.
Чотири висновки з результату
- Однакові серійні номери означають, що провайдер закінчив. Той самий серійний номер SOA на кожному сервері імен означає, що зміна вийшла від провайдера; решта - кеші. Anycast-сервери можуть відрізнятися залежно від місця, тож це правда для точки, з якої ви питаєте. Якщо номери різні, чекайте або відкривайте тікет: жоден трюк із TTL не допоможе.
- Резолвери відраховують, а не оновлюються раніше. У Quad9 для www.cloudflare.com лишалося 181 с, у резолвера Cloudflare - 242 с. Зміна в ту мить дійшла б до їхніх користувачів за три-чотири хвилини, хоч якою швидкою була б збірка. Для dcxv.com таке очікування може тривати 30 хвилин, бо наш A-запис має TTL 1800 с.
- Нове ім'я може з'явитися пізніше, ніж змінене. Якщо хтось шукав ім'я ще до його створення, резолвер може зберігати відповідь "такого імені немає" до мінімуму SOA: 3600 с у нашій зоні. Створюйте нові імена хостів до того, як про них оголошувати.
- Зміна серверів імен - це інший масштаб. Делегування в .com має 172800 с, тобто два дні. Перенесення DNS до іншого провайдера означає, що обидва провайдери щонайменше стільки обслуговують однакові зони.
План перемикання на новий сервер або новий блок IPv4
- За один старий TTL до перемикання: знизьте A- і AAAA-записи до 300 с. Повний чекліст - у статті як перенести сайт на хмарний сервер.
- Під час перемикання: змініть записи, запускайте
dnscut.js, доки серійні номери не збіжаться, а потім стежте, як TTL резолверів відраховують до нової адреси. Тримайте старий сервер увімкненим, доки його логи не затихнуть. - Якщо змінюються сервери імен: спершу зберіть нову зону, перемкніть NS у реєстратора й залиште старого провайдера з тими самими записами щонайменше на два дні після цього.
- Нові адреси: якщо разом із переїздом приходить щойно куплений або орендований блок, перевірте зворотний DNS і геолокацію до появи трафіку; див. як виправити геолокацію IPv4 після трансферу і наш IPv4-брокеридж.
- Через тиждень: знову підніміть TTL (1800-3600 с - звичне значення), щоб короткий збій провайдера не спустошив усі кеші за кілька хвилин.
Сплануйте переїзд разом із нами
Наші дата-центри Tier III у Празі та Ковільяні мають хмарні сервери і виділені сервери. Запустіть хмарний сервер, виконайте dnscut.js для своєї зони за день до переїзду й надішліть результат на sales@dcxv.com: ми допоможемо спланувати перемикання.
