Wirewiki довёл автокомплит по 240 млн доменам до p99 0 мс

Автор сервиса Wirewiki.com (инструмент для проверки интернет-инфраструктуры, DNS-записей, делегирования, настроек доставки почты и так далее) рассказывает, как довёл автокомплит доменных имён на сайте до ощущения мгновенного отклика. Похожих сервисов на рынке становится всё больше (в том числе из-за «вайб-кодинга»), поэтому автор решил выделяться качеством инструмента и UX, а автокомплит на Wirewiki это основной способ навигации, так что к его скорости особые требования.

Технический приём: на keyDown (нажатие клавиши) клиент заранее запрашивает подсказки, для введённого символа и для возможного следующего; к моменту keyUp (отпускание клавиши) эти подсказки уже готовы к отрисовке. Так получается бюджет времени, равный сумме длительности двух нажатий клавиш и паузы между ними, а не произвольный дедлайн «на глаз». Замерив собственную скорость печати на 100 доменных именах, автор получил p99-бюджет в 121 мс. Для сравнения: экран с частотой 60 Гц обновляется каждые 16,7 мс, на медиане это даёт около 8,33 мс дополнительного запаса, но на p99 запас почти нулевой.

Под эту цифру подстроен бэкенд, разделённый на «голову» и «хвост». «Голова», топ-1 млн доменов из списка Tranco, хранится в оперативной памяти как символьное дерево (trie): для каждого префикса заранее посчитаны топ-8 подсказок, поиск, это проход по нескольким указателям со сложностью O(длины введённого текста). «Хвост», все 240 млн доменов из списка CZDS (он покрывает домены в общих зонах вроде .com.net.org, но не в национальных зонах типа .uk.de.fr, впрочем, заметный трафик по таким доменам и так попадает в Tranco), лежит на SSD в виде отсортированных и дельта-сжатых блоков по 256 доменов с компактным индексом-каталогом на 27 МБ в памяти; поиск, это бинарный поиск по каталогу и последовательное сканирование одного блока, а весь массив занимает около 2,5 ГБ на диске.

Результат проверили нагрузочным тестом: LLM сгенерировала 720 тысяч запросов-на-нажатие клавиши, имитируя ввод 60 тысяч доменных имён, и трафик проиграли в режиме «открытого цикла» (запросы идут с фиксированной частотой независимо от скорости ответов), отдельно на самом API, через Nginx и по полной цепочке. Большинство запросов API обрабатывает быстрее чем за 2 мс; даже при нагрузке 1,6 тысячи запросов в секунду связка Nginx и API укладывается в 15 мс в 99% случаев.

Но в заголовке не зря стоит звёздочка. На практике задержка автокомплита равна времени прохождения запроса от браузера через Cloudflare до сервера плюс около 10 мс, а сервер у автора один и стоит в Европе. Пользователи из США получают дополнительные 100, 200 мс, что выбивает их из 121-миллисекундного бюджета на p99; кэширование частых запросов на CDN и порог «мгновенности» в 0,1 секунды по Нильсену сглаживают проблему, но не решают её целиком. Чтобы честно добиться p99 0 мс для всех, нужны несколько серверов с гео-балансировкой нагрузки, но, по словам автора, для его проекта это «многовато, даже для меня». Строить на этом инструменте отдельный бизнес он считает нишевой затеей, но готов пересмотреть позицию, если найдутся желающие платить за доступ к API.

Ключевые факты

  • Приём prefetch на keyDown / render на keyUp даёт реальный (не придуманный) бюджет времени, сумму двух нажатий клавиш и паузы между ними; замер на своей печати дал p99-бюджет 121 мс
  • Бэкенд разделён на «голову», trie в памяти для топ-1 млн доменов Tranco, и «хвост», SSD-индекс из дельта-сжатых блоков по 256 доменов (27 МБ каталог) для всех 240 млн доменов CZDS, занимающих около 2,5 ГБ
  • Нагрузочный тест: LLM сгенерировала 720 тысяч запросов из 60 тысяч имитируемых доменных имён; сам API отвечает быстрее чем за 2 мс, связка Nginx + API, за 15 мс на p99 при 1,6 тыс. запросов в секунду
  • Реальная задержка ≈ время в оба конца через Cloudflare плюс 10 мс; единственный сервер в Европе даёт пользователям из США дополнительные 100, 200 мс, это и есть звёздочка в «p99 0 мс*» из заголовка
  • Чтобы закрыть звёздочку, нужна гео-распределённая инфраструктура из нескольких серверов; автор считает это «многовато» для нишевого проекта, но готов передумать ради платящих клиентов API

Почему это важно

Это редкий для ленты пример инженерного поста, где задержка не постулируется маркетингово («у нас всё мгновенно»), а выводится из измерения: сколько реально длится нажатие клавиши у живого человека, и под эту цифру спроектирован весь бэкенд. Такой подход к latency-бюджетам переносим далеко за пределы автокомплита доменов. Отдельно показателен и способ нагрузочного тестирования, LLM сама сгенерировала 720 тысяч реалистичных запросов для стресс-теста, это практический пример использования модели не для написания кода, а для инженерной проверки готовой системы.

Кому это важно

Инженерам, которые проектируют поиск, автокомплит или любой другой UI с жёстким требованием к отклику; бэкенд- и инфраструктурным разработчикам, которые выбирают между in-memory индексом и диском для больших наборов данных; авторам DNS-, whois- и доменных инструментов, рынок таких сервисов, по словам автора, растёт особенно быстро.

Как это применить

Ключевые шаги воспроизводимы в других проектах: во-первых, измерить реальный бюджет времени (в данном случае, скорость печати пользователей), а не выдумывать SLA; во-вторых, начинать запрос подсказок на keyDown и рендерить их на keyUp, используя паузу между нажатиями как скрытый запас времени; в-третьих, разделить набор данных на «горячую» часть в оперативной памяти (символьное дерево для самых частых значений) и «холодную» на SSD (сжатый блочный индекс с компактным каталогом), это удерживает и скорость, и объём под контролем; в-четвёртых, нагрузочно тестировать систему трафиком, сгенерированным LLM и воспроизведённым в режиме открытого цикла, отдельно на каждом слое (API, прокси, весь путь).

Можно ли доверять

Источник, подробный технический пост от первого лица с конкретными измеренными цифрами (латентность API, объёмы нагрузочного теста, размеры индексов), без маркетинговых обещаний и без утаивания слабых мест: автор сам вводит звёздочку в заголовок и объясняет, что она означает. Имя автора в тексте не названо (только домен ruurtjan.com намекает на него), поэтому в пересказе оно не используется. Это личный блог-пост без внешней рецензии, так что все цифры, собственные измерения автора, а не результат независимого аудита.

Риски и подводные камни

Заявленный «p99 0 мс» верен только локально: единственный сервер в Европе означает, что пользователи из США и других удалённых регионов регулярно выходят за пределы 121-миллисекундного бюджета, это и есть смысл звёздочки в заголовке. Автор не называет ни одного конкурирующего инструмента для сравнения, хотя сам пишет, что похожих сервисов много и их число растёт. Планов и сроков на гео-распределённое масштабирование нет, только формулировка «можно было бы, но это многовато». Наконец, сам автор не уверен, что на этой технологии есть бизнес: считает её нишевой и готов пересмотреть мнение только при появлении платящих клиентов.

«Мне кажется, это слишком нишевая штука, чтобы строить на ней отдельный бизнес. Но если вы готовы платить за доступ к этому API, напишите мне, я могу передумать.»

— автор Wirewiki