4 ms·
I doubt their choice of implementing something so performance-critical as a DNS server in JavaScript. It seems like a slow language for that purpose. When I wa
by maxloh 1y ago
I doubt their choice of implementing something so performance-critical as a DNS server in JavaScript. It seems like a slow language for that purpose.
When I was looking for ad-block solutions on Android, Rethink DNS was actually on the top of my list. However, when I found out that their server was written in JavaScript, I did some benchmarking.
Rethink's server processed DNS requests in 400-500ms, which could potentially make a new webpage render up to half a second slower the first time:
~ > curl -w "DNS Time: %{time_namelookup}s\nConnect: %{time_connect}s\nTotal: %{time_total}s\n" -H "accept: application/dns-message" -H "content-type: application/dns-message" --data "<binary-data>" -o nul -s https://sky.rethinkdns.com/1:6AcDACIBLIDAAFQwIAAACA==
DNS Time: 0.004995s
Connect: 0.142332s
Total: 0.462496s
While the Cloudflare's server took just 5-10ms, as seen below:
~ > curl -w "DNS Time: %{time_namelookup}s\nConnect: %{time_connect}s\nTotal: %{time_total}s\n" -H "accept: application/dns-message" -H "content-type: application/dns-message" --data "<binary-data>" -o nul -s 1.1.1.1
DNS Time: 0.000026s
Connect: 0.006273s
Total: 0.008822s
In the end, I chose AdAway and have stuck to that choice.
- ignoramous 1y ago> Rethink's server processed DNS requests in 40-60ms, which could potentially make a new webpage render up to 50ms slower the first time, while the system default took just 5-10ms You can choose "system default" in the Rethink Android app from Configure -> DNS -> System DNS. You don't have to use Rethink's DoH (DNS over HTTPS) / DoT (DNS over TLS) servers. You can setup any DNSCrypt, Oblivious DoH, or plain old DNS endpoint with Rethink to forward DNS requests to. > I chose AdAway and have stuck to that choice for now A decent choice. A word of caution when using it in non-root mode, though: AdAway borrows code from another (now discontinued but pretty solid) project viz. DNS66. From when I looked at the code, DNS66 never handled DNS over TCP. You can test this with Termux: dig +tcp example.com A. > doubt their choice of implementing something so performance-critical as a DNS server in JavaScript For a remotely-hosted DNS resolver, network latency & concurrency is likely to dominate than performance of the code itself. You're right that JS is slow (as compared to Rust, say), but looking at metrics from serving 300m to 3bn queries/day on Cloudflare, our median (CPU time) spent processing a DNS request was consistently less than 2ms, and IO wait (there are no "disks" so, this is mostly hitting the caches or upstream resolvers) was estimated to be less than 7ms. Also, we employ a bunch of optimizations on client & the server, as appropriate (if we're missing any we should implement, let us know). - Coalesce multiple requests into one upstream request: For example, if there's 40 clients all wanting to resolve the same domain (say, ipv4only.arpa) within milliseconds of each other, only one request is upstreamed. - Utilize in-process LFU cache and Cloudflare's Cache API to avoid upstreaming where possible. - Connection pool egress to avoid reconnect overheads. - Race response for a query from multiple upstreams in parallel. - Support TLS session resumption. - Prefer the lighter TLS_AES_128_GCM_SHA256 cipher suite. - Dynamically adjust the TLS frame size. DNS queries aren't that big. - Disable Nagling on TCP. - Rehydrate responses for top domains stored in the in-process cache in the background. - Admission Control (load shedding) & queuing disciplines (CoDel etc) --- > curl -w "DNS Time: %{time_namelookup}s\nConnect: %{time_connect}s\nTotal: %{time_total}s\n" -H "accept: application/dns-message" -H "content-type: application/dns-message" --data "<binary-data>" -o nul -s 1.1.1.1 Shouldn't the switch "-s" be "https://one.one.one.one/dns-query https://one.one.one.one/dns-query"? For DoH perf specifically, I use https://github.com/ameshkov/godnsbench https://github.com/ameshkov/godnsbench as it supports parallel and cache-busting (random) queries. Ex: Rethink on Workers: ./godnsbench -a https://sky.rethinkdns.com/dns-query -p 10 -c 300 -t 1 -q {random}.dnsleaktest.com godnsbench with the following configuration: { "Address": "https://sky.rethinkdns.com/dns-query", "Connections": 10, "Timeout": 1, "QueriesCount": 300, } The test results are: Elapsed: 6.120078941s Average QPS: 49.018394 Processed queries: 300 Average per query: 20.400765ms Errors count: 0 Cloudflare 1.1.1.1: ./godnsbench -a https://cloudflare-dns.com/dns-query -p 10 -c 300 -t 1 -q {random}.dnsleaktest.com godnsbench with the following configuration: { "Address": "https://cloudflare-dns.com/dns-query", "Connections": 10, "Timeout": 1, "QueriesCount": 300, } The test results are: Elapsed: 6.780474724s Average QPS: 44.244383 Processed queries: 299 Average per query: 22.677588ms Errors count: 1
- maxloh 1y agoI was able to reproduce your results with the provided command. In that case, Rethink DNS is 1-2 ms faster than Cloudflare DNS. However, the provided command actually runs 300 queries in a really short timeframe (specified by -c 300), which is very different from real-world use cases — in most cases, we look up a domain only once, and the result is cached by the OS. If we set the count parameter to 1 (closer to the mentioned real-world use cases), we can reproduce the result in my comment above. Rethink DNS actually takes 450 ms to return a response. ./godnsbench -c 1 -q google.com -a https://sky.rethinkdns.com/dns-query ... 2025/05/04 23:22:47 [info] Average per query: 452.3948ms With Cloudflare DNS, it takes only 35 ms, even when using DNS over HTTPS. ./godnsbench -c 1 -q google.com -a https://cloudflare-dns.com/dns-query ... 2025/05/04 23:22:49 [info] Average per query: 34.4343ms As sky.rethinkdns.com is hosted on Cloudflare, there shouldn't be any notable network differences between Rethink DNS and Cloudflare DNS. If you inspect the list of servers in the following two lists, they are almost identical. - https://check-host.net/check-ping?host=https://sky.rethinkdns.com https://check-host.net/check-ping?host=https://sky.rethinkdn... - https://check-host.net/check-ping?host=https://cloudflare-dns.com https://check-host.net/check-ping?host=https://cloudflare-dn... If CPU time isn't the bottleneck of response time, any idea what the reason is behind the difference in response time?
- e12e 1y agoReally appreciate both of you commenting here. Could the ~430ms be startup time for a sleeping worker? Or is it the cost for a cache miss? Ed: hm, I suppose google.com should pretty much always be a cache hit... Unless they have some really strange TTLs?
- maxloh 1y agoActually, 450 ms was already a cache hit. The response time would be 530 ms on the first query of google.com: ./godnsbench -c 1 -q google.com -a https://sky.rethinkdns.com/dns-query ... 2025/05/05 02:50:14 [info] Average per query: 532.1144ms Subsequent queries for google.com within a few minutes would result in a slightly shorter response time, like my second comment above. ./godnsbench -c 1 -q google.com -a https://sky.rethinkdns.com/dns-query ... 2025/05/05 02:50:48 [info] Average per query: 468.5749ms ./godnsbench -c 1 -q google.com -a https://sky.rethinkdns.com/dns-query ... 2025/05/05 02:55:04 [info] Average per query: 472.1229ms Some of the lengthy response times originate from the overhead of DNS over HTTPS. If we switch to the DNS over TLS version of Rethink DNS, there will be about a 240-320 ms improvement in response time. ./godnsbench -c 1 -q google.com -a tls://max.rethinkdns.com ... 2025/05/05 02:50:26 [info] Average per query: 290.4762ms ./godnsbench -c 1 -q google.com -a tls://max.rethinkdns.com ... 2025/05/05 02:50:51 [info] Average per query: 145.1868ms However, 290ms is still quite a large delay for DNS queries, which makes webpage rendering a quarter of a second slower the first time you visit it.
- pjmlp 1y agoIndeed, then someone rewrites it in a compiled language and we get yet another "40x improvement" blog post.
- ignoramous 1y ago> 40x improvement Could WASM AoT bring about those? ;) > rewrites ... compiled language With stuff like AutoFDO on Android, we've come a full circle with folks "JITing" compiled blocks... https://lwn.net/Articles/995397/ https://lwn.net/Articles/995397/
- pjmlp 1y agoWe have, yet > Propeller requires specific software and hardware support to do its job WASM AoT is nothing special, we have had plenty of those since UNCOL (1958). Two of the oldest systems using bytecode as distribution format are Burroughs from 1961, nowadays Unisys ClearPath MCP, and IBM AS/400 from 1988, nowadays IBM i. This while not bothering to actually list all the products and attempts between 1958 and 2025. Naturally on the magpie developer culture it is easier to sell shinny new, than having people caring about our history.