P99 0ms* autocomplete for 240M domain names

pul1 pts1 comments

p99 0 ms* autocomplete for 240 million domain names - Ruurtjan Pul

We’ll get to the asterisk.

I run Wirewiki.com, a website to inspect internet infrastructure like domain names. It helps people check (historic) DNS records,<br>DNS delegation, email deliverability config, etc.

There are a ton of sites that offer this (growing faster than ever thanks to vibe coding), so I need<br>a way to stand out. I picked tool quality / usefulness and UX.

The autocomplete is the main way to navigate Wirewiki, so it should be as complete, accurate and fast as possible.<br>I want it to be instant. Like, next frame instant.

I've mostly achieved that. Try for yourself:

replaced with inlined SVGs; leak-guard utilities (text-gray-900 / no-underline)<br>added so page prose CSS cannot tint the white card. Driven by the real command-palette.js below. -->

$refs.searchInput.focus())">

DNS root

Your IP

Tab<br>Cycle tabs

Navigate

Open

Here's how.

On keyDown (the user starts pressing a key), we prefetch the suggestions for the typed character + any next character. And on keyUp (the user releases the key), we render the suggestions.

GET /autocomplete?q=wi

"results": ["wikipedia.org", "windowsupdate.com", "windows.net", "windows.com", "wixsite.com", "wikimedia.org", "wiley.com", "wildberries.ru"],

"next": {

"-": ["wi-fi.ru", "wi-fi.org", "wi-fi.click", "wi-tribe.ph", "wi-cat.ru", "wi-fi.link", "wi-power.com", "wi-fi.com"],

".": ["wi.gov", "wi.us", "wi.infomart.co.jp", "wi.net", "wi.likebtn.com", "wi.accountants", "wi.agency", "wi.amsterdam"],

"0": ["wi0.buzz", "wi0.com", "wi0.mobi", "wi0.site", "wi0.tech", "wi0.top", "wi0.xyz", "wi00.com"],

"9": ["wi9-h.com", "wi9.casino", "wi9.com", "wi9.lol", "wi9.mobi", "wi9.org", "wi9.top", "wi9.xyz"],

"a": ["wiadomosci.wp.pl", "wiadomosci.onet.pl", "wiadomosci.gazeta.pl", "wialon.com", "wialon.host", "wiair.com", "wiara.pl", "wiadomosci.radiozet.pl"],

"k": ["wikipedia.org", "wikimedia.org", "wiktionary.org", "wikihow.com", "wikia.com", "wikisource.org", "wikibooks.org", "wikidot.com"],

"z": ["wizzair.com", "wizards.com", "wiz.world", "wiz.biz", "wiz.io", "wiz.cn", "wizardingworld.com", "wizaz.pl"]

That gives us a time budget of keyPress1Duration + gap between key presses + keyPress2Duration. If the API returns before the end of the second key press, we'll have the results ready in time.

(A 60 Hz display renders every 16.7 ms. So we technically have 8.33 ms extra time budget at p50, but near 0 ms at p99.)

Key released<br>Key pressed

GET /autocomplete?q=wi

Render<br>completions for ‘wik’

Time budget of the API

Latency

API round-trip time

The request for q=wi fires the instant i is pressed; if its response lands before k is released, completions for wik render with zero perceived latency.

So for the purpose of this article, we'll define latency as keyUp to results ready for rendering. p99 0 ms means that 99% of the time, the results will be ready before the user even releases the key.

We need two things to make this happen:

Client side prefetching and caching of the suggestions, and

An API that's fast enough.

Aside

What about bandwidth?

This was my concern initially. But it turns out not to be an issue. There are only 38 valid domain name characters: a-z, 0-9, - and .. That sets the upper limit of (38 + 1) * 8 = 312 domain names in the response.

In practice, that works out to a max of about 5 kB of data per request. 2.5 kB goes over the wire after compression.

Given that 50-100 kB is generally considered a healthy image size, an equivalent would be 20-40 characters typed.

I've never thought twice about including an image on a page because of the bandwidth usage, so I think I'm happy with this.

How big is the budget?

We now know that we can spend two key press durations and a gap duration, but how long is that in milliseconds?

I've measured it while typing 100 domain names reasonably fast and found that p99 works out to 121 ms for me.

Here are my results. You can start typing to see what it is for you.

Measuring the latency budget

This measures the time from one key press to the next release. The slider tells you what % of keystrokes would render next-frame at a given API latency.

121 ms

next-frame at 121 ms latency

% next-frame vs. latency. Vertical line = slider.

Per-keystroke budget (ms). Bars left of the line miss at the current latency.

Type some domains to populate.<br>Reset

How fast can we make the API?

Okay, so we've got a latency target of 121 ms. But how fast can we make the API?

I'm using the Tranco list of the top 1 million most popular domains for this API. These should be suggested first, and supplemented by any other domain name currently in use.

CZDS offers the list of all domains for most of the gTLDs (like .com, .net, .org). ccTLDs (like .uk, .de, .fr) are unfortunately not available. But domains for those with any meaningful traffic will be in the Tranco list anyway. There are other sources, like certificate transparency logs and Archive.org that...

latency domain next time budget autocomplete

Related Articles