• v0.0.28
    Gates / frontend (push) Successful in 2m11s
    Gates / test (push) Successful in 3m25s
    Site / deploy (push) Successful in 2m8s
    Gates / test-aarch64 (push) Successful in 6m29s
    Gates / package (push) Successful in 6m35s
    Gates / container (push) Successful in 9s
    CI / gates (push) Successful in 16m39s
    Release / guard (push) Successful in 3m47s
    Gates / frontend (push) Successful in 1m59s
    Gates / test (push) Successful in 3m10s
    Gates / test-aarch64 (push) Successful in 6m14s
    Gates / package (push) Successful in 6m45s
    Gates / container (push) Successful in 8s
    Release / gates (push) Successful in 16m19s
    Release / publish (push) Successful in 10m58s
    Stable

    mokhtar released this 2026-11-05 20:47:09 +00:00 | 0 commits to master since this release

    Added

    • Memory and threads in /metrics. process_resident_memory_bytes, process_resident_memory_anon_bytes, process_resident_memory_peak_bytes and process_threads report what the kernel counts for the nxdns process. The peak is the most since start, so a blocklist refresh that peaks between two scrapes still shows. A reading nxdns could not take is left out of that scrape rather than reported as zero, and nxdns_process_sample_failures_total counts those scrapes.

    Artifacts

    85f0f93b8431b49fadf70502d39ef0646cde21a872fc4614bdfafc4363d23151  nxdns-0.0.28-x86_64-linux-musl.tar.gz
    a4eabddcaca922c39aec0a14167db39883e739d97088e7d932abe0f111091b18  nxdns-0.0.28-aarch64-linux-musl.tar.gz
    6c94fec27ba1aa9eaae07c18a9733158366ad429f5028f2b06b3a15fedbaf3e7  IMAGE-DIGEST.txt
    
    git.mial.net/mokhtar/nxdns:0.0.28@sha256:19c79d115513971f2d70d11289f8a1048ca8441d79548898e320062baaf64629
    

    Compare v0.0.27...v0.0.28

    Commits since v0.0.27
    65089eb build: bump version to 0.0.28
    8286992 changelog: date the 0.0.28 section
    0ff22c3 metrics: export resident memory, anonymous memory, peak and threads
    
    Downloads
  • v0.0.27
    Gates / frontend (push) Successful in 1m57s
    Gates / test (push) Successful in 3m2s
    Site / deploy (push) Successful in 1m59s
    Gates / test-aarch64 (push) Successful in 6m28s
    Gates / package (push) Successful in 6m28s
    Gates / container (push) Successful in 9s
    CI / gates (push) Successful in 16m11s
    Release / guard (push) Successful in 3m41s
    Gates / frontend (push) Successful in 1m53s
    Gates / test (push) Successful in 2m52s
    Gates / test-aarch64 (push) Successful in 6m2s
    Gates / package (push) Successful in 6m34s
    Gates / container (push) Successful in 8s
    Release / gates (push) Successful in 15m38s
    Release / publish (push) Successful in 12m31s
    Stable

    mokhtar released this 2026-10-31 09:00:16 +00:00 | 3 commits to master since this release

    Changed

    • Built with Zig 0.17.0. The release binaries now allocate through Zig's checked allocator instead of the C library's, so a double free stops the process instead of corrupting memory. On a test machine with eight blocklists, memory held flat across six blocklist refreshes, where 0.0.26 grew by about 0.2 MiB with each. Building from source needs Zig 0.17.0.

    Artifacts

    3a9b58326e0a1a215d129b9c12c6d039dafdc726100374d7f9b14384aa80c6b2  nxdns-0.0.27-x86_64-linux-musl.tar.gz
    4e456e60f17dc679a7633660b0a79962b9d1e2c45fb31f2176247514bb355f93  nxdns-0.0.27-aarch64-linux-musl.tar.gz
    cb793c1c09d7b6955db9d222d58040f09031faa7f0173e0f409999f73d96a2ae  IMAGE-DIGEST.txt
    
    git.mial.net/mokhtar/nxdns:0.0.27@sha256:151768ef613ff1d7acf1b91f74bbbd5d5b51411136bb74afd286111b080760f8
    

    Compare v0.0.26...v0.0.27

    Commits since v0.0.26
    cdaa3fc build: bump version to 0.0.27
    c3411d2 changelog: date the 0.0.27 section
    ad60f76 bench: build again after the cache byte budget, and compile it with test
    cb95ce1 zig: replace the names 0.17.0 deprecates and apply its zig fmt
    56717a1 build: port to zig 0.17.0
    d2de02a website: comparison gains a resource row, and its cells are reworded for plain language and fairness
    2032ab0 specs: record the 0.0.26 memory reading on the pi
    3fd73ca website: a 2080 px screenshot width, so 2x screens stop upscaling the 1440 px copy
    1003024 website: screenshots retaken on 0.0.26 without the version footer, and the adguard home signing cell corrected
    
    Downloads
  • v0.0.26
    Gates / frontend (push) Successful in 1m50s
    Site / deploy (push) Successful in 1m48s
    Gates / package (push) Successful in 4m10s
    Gates / test (push) Successful in 2m18s
    Gates / test-aarch64 (push) Successful in 6m5s
    Gates / container (push) Successful in 6s
    CI / gates (push) Successful in 16m36s
    Release / guard (push) Successful in 1m38s
    Gates / frontend (push) Successful in 1m52s
    Gates / test (push) Successful in 2m20s
    Gates / test-aarch64 (push) Successful in 5m30s
    Gates / package (push) Successful in 32s
    Gates / container (push) Successful in 6s
    Release / gates (push) Successful in 8m28s
    Release / publish (push) Successful in 10m58s
    Stable

    mokhtar released this 2026-10-26 11:53:17 +00:00 | 12 commits to master since this release

    Added

    • Clear the DNS cache from the System page. "Clear DNS cache" empties it and says how many answers it removed; POST /api/cache/flush does the same. It works when the configuration comes from a file too. /metrics counts flushes as nxdns_cache_flushes_total and the answers they removed as nxdns_cache_flushed_entries_total.

    Fixed

    • Blocking a CNAME target takes effect on cached answers. A name cached before its CNAME target was blocked, or while blocking was paused, kept resolving until its cached answer expired. Cached answers are now checked against the current blocklists every time they are served.
    • Changing forward zones or upstream servers no longer leaves old answers cached. Adding a forward zone kept serving what the upstream had said about its names, including "no such name", and removing one kept serving the zone's own answers, each until they expired. Adding, editing or removing a local record, a forward zone or an upstream server now empties the cache, and an answer that was still being fetched when it emptied is not stored; /metrics counts those as nxdns_dns_cache_stale_stores_total. Changing an upstream timeout keeps the cache.
    • Updating the blocklists by hand builds them once. "Update now" in the web interface, or POST /api/blocklists/update, rebuilt and published the blocklists a second time right after the refresh had already done so, which cost a second full build and advanced the snapshot generation twice. The scheduled refresh was not affected.

    Artifacts

    ed73a9f9da294e71174fec791acdb1e2354adb85487f881e61d6dcdf7211dc23  nxdns-0.0.26-x86_64-linux-musl.tar.gz
    7e12d7ddbea28d52bc39a34cf0881f3f30607c4cd778212d6ebcc5d6d1a1dcdd  nxdns-0.0.26-aarch64-linux-musl.tar.gz
    6a5f657000ad1a3849da354021b78e0f86753877572d01ac7ca662688ba56366  IMAGE-DIGEST.txt
    
    git.mial.net/mokhtar/nxdns:0.0.26@sha256:c4034cbfed34972e3a2103449f751a5a8b0ec1327deed2444d468e56c9ece726
    

    Compare v0.0.25...v0.0.26

    Commits since v0.0.25
    186ffc2 build: bump version to 0.0.26
    f126379 changelog: date the 0.0.26 section
    4f14cf0 changelog: count the pi's blocklist entries once
    50f4a8c changelog: record the 0.0.25 memory measurement
    9fe5944 specs: record the 0.0.25 memory measurement from the pi
    34a429f dns: clear the cache on request and when local tables or upstream servers change; uncloak cached answers
    2273fda web: a manual blocklist refresh publishes once, since refreshAll already ends in its own reload
    
    Downloads
  • v0.0.25
    Gates / container (push) Successful in 10s
    CI / gates (push) Successful in 23m56s
    Release / guard (push) Successful in 1m47s
    Gates / frontend (push) Successful in 2m14s
    Gates / test (push) Successful in 2m40s
    Gates / test-aarch64 (push) Successful in 5m39s
    Gates / package (push) Successful in 47s
    Gates / container (push) Successful in 11s
    Release / gates (push) Successful in 9m20s
    Gates / frontend (push) Successful in 2m12s
    Release / publish (push) Successful in 10m46s
    Gates / test (push) Successful in 2m32s
    Gates / test-aarch64 (push) Successful in 6m35s
    Gates / package (push) Successful in 4m31s
    Stable

    mokhtar released this 2026-10-22 19:34:55 +00:00 | 19 commits to master since this release

    Fixed

    • The DNS cache's memory is bounded in bytes, not only in entries. Each cached answer is copied at whatever size the upstream sent, so 10000 entries could in principle hold 10000 large answers. The answers now share a budget of 256 bytes per cache.size entry, about 2.4 MiB at the default, and when a new answer does not fit, answers nobody has asked for lately make room for it. An answer larger than the whole budget is not cached. /metrics reports nxdns_cache_response_bytes against nxdns_cache_max_bytes, and counts nxdns_cache_oversized_total and nxdns_cache_copy_failures_total.
    • The DNS cache no longer evicts an answer while it has free room. A new answer replaced an older one whenever the eviction scan met it first, even with most of the cache empty. A copy of an answer that failed for lack of memory was also dropped without a trace; it is now counted, and a failed replacement keeps the answer already cached.
    • A refused query history says what to do. When nxdns refuses to open querylog.db, because a newer release wrote it or it cannot be converted, the message now gives the remedy: run the newer release again, put back the querylog.db.pre-migrate-* copy, or move the file and its -wal and -shm files aside to start an empty history. It used to point at a documentation page.
    • A refused start no longer gives advice that does not apply. After a query history refusal, nxdns run also printed "run nxdns check" and "load one with nxdns import <file>", though the configuration was fine. The import hint now appears only when the database has no usable upstream, and neither hint follows a database refusal.

    Changed

    • Blocklists take less memory, and a refresh peaks lower. A list that names a domain both on its own and with its subdomains, as Adblock-style lists do for every entry, now stores that name once instead of twice. A reload reads one list's compiled files at a time instead of all of them at once, and the startup pass no longer rebuilds the blocklists when no list was due for a refresh.
    • The query-history buffer defaults to 1024 queries instead of 10000, under 2 MiB instead of about 17. It only holds queries that arrive while a write is in progress.
    • A live query stream takes memory only while someone watches it. Each of the 32 possible streams reserved its buffer at startup, about 3.6 MiB in all. A stream that cannot get its buffer is refused with its own message and counted in nxdns_live_stream_allocation_failures_total.
    • All DNS listeners share one budget of 64 queries at a time, about 4.6 MiB, where each UDP and TCP listener used to reserve room for 64 of its own, about 27 MiB across the four. The Pi's busiest moment over a day was 27 queries at once. A query beyond the budget waits for a free one instead of failing: over UDP it waits in the system's socket buffer, over TCP, DoT and DoH for at most the connection's idle time. /metrics counts the waits as nxdns_dns_query_permit_waits_total, their time as nxdns_dns_query_permit_wait_seconds_total and stream waits that ran out as nxdns_dns_query_permit_wait_timeouts_total, shows nxdns_dns_query_permits_waiting, and reports what the system holds and drops for the UDP/53 sockets as nxdns_udp_server_receive_queue_bytes and nxdns_udp_server_kernel_drops_total. TCP, DoT and DoH each accept 16 connections at a time instead of 64, and the DoT and DoH listeners now report rejected_at_capacity_total too.
    • A query waiting for its turn at an upstream holds one thread instead of three, so a burst grows the server's thread pool less, and transparent huge pages are switched off for the process, so a thread's stack no longer holds 2 MiB on systems that enable them for everything. Work that could not get a thread used to fail as a generic error or not be counted at all; /metrics now counts it as nxdns_concurrency_unavailable_total, by where it happened.
    • Each database connection keeps a page cache sized for its job instead of SQLite's 2 MiB default on all seven: 256 KiB for the configuration database and for retention, 1 MiB for the query-history writer and reader.
    • The documentation is written for people running nxdns. It starts from Get started, which downloads a release instead of building from source, and drops the API reference, the troubleshooting page and the performance pages. It is published at https://nxdns.sh/docs/, and INSTALL.md in the tarball links there.

    Removed

    • nxdns_udp_server_dropped_no_slot_total, because a UDP query is no longer dropped for lack of room: it waits. A query still waiting when the listener shuts down is counted in the new nxdns_udp_server_dropped_at_shutdown_total.

    Artifacts

    b49d3f980d198627344aa621c1aacd28b94ad2ce5005013337fe764141b162fd  nxdns-0.0.25-x86_64-linux-musl.tar.gz
    ccada2e757115fee6afbdac845abf89ba36155924963083d3898f45acb4a77f3  nxdns-0.0.25-aarch64-linux-musl.tar.gz
    8cc3f364a797022e86e78e3877de851f8110cd087244790026bddbd806d1e6b6  IMAGE-DIGEST.txt
    
    git.mial.net/mokhtar/nxdns:0.0.25@sha256:c225e4604ad3edaade1346060679659ed081ccd3cfee50e93b5b1026d2d60035
    

    Compare v0.0.24...v0.0.25

    Commits since v0.0.24
    27e1e49 platform: the huge pages test skips where the kernel or emulator has no such switch
    98283e1 ci: install the pinned node from its tarball instead of trusting the runner image
    f834418 build: bump version to 0.0.25
    90b022f changelog: date the 0.0.25 section
    91ed5ae server: a query that finds every permit taken waits for one instead of failing, the budget is 64, permit and upstream turns wait on a futex with one thread each, the thread pool has no task limit, and transparent huge pages are off for the process
    63cc5f8 server: every dns listener shares one budget of 32 queries, stream listeners take 16 connections, the task pool is capped from those bounds, and work it cannot start is counted by site
    e4e405f cache: a byte budget of 256 bytes per entry bounds the cached answers, evicting by clock, and a full or failed copy is counted instead of swallowed
    d951d03 querylog: the writer queue defaults to 1024 entries, and a live stream allocates its ring on subscribe instead of at boot
    0cafd77 filter: a reload builds the snapshot one source at a time, and the startup pass reloads only when a source changed or was not enforced
    c2eac8d storage: each runtime database connection keeps a page cache sized for its role, read back at open
    8f27945 ci: time limits on the test, test-aarch64, package and container jobs
    5a51e2d tests: a failed server check fails the test instead of hanging it, and the tls idle tests leave the handshake room
    4916b01 filter: store each blocklist name once, flagged exact and subdomains, instead of in two sets per source
    2a06239 ci: use the runner image's node instead of setup-node, which downloaded it again on every run
    7e06642 ci: build nxdns.sh and deploy it as a cloudflare worker with static assets
    93e2683 website: nxdns.sh on astro and starlight, with the docs and 0.0.24 screenshots
    c21e5a9 docs: rewrite for people running nxdns; query-history refusals name their remedy and a refused start gives no wrong hints
    fbc8fd7 specs: memory budget drops the removed performance page and keeps stack_size, a thp artifact explained the 2 mib stacks
    
    Downloads
  • v0.0.24
    Gates / container (push) Successful in 17s
    CI / gates (push) Successful in 7m14s
    Release / guard (push) Successful in 38s
    Gates / frontend (push) Successful in 2m30s
    Gates / test (push) Successful in 2m38s
    Gates / test-aarch64 (push) Successful in 7m43s
    Gates / package (push) Successful in 46s
    Gates / container (push) Successful in 18s
    Release / gates (push) Successful in 11m29s
    Release / publish (push) Successful in 5m19s
    Gates / test (push) Successful in 2m24s
    Gates / test-aarch64 (push) Successful in 7m45s
    Gates / frontend (push) Successful in 2m4s
    Gates / package (push) Successful in 4m44s
    Stable

    mokhtar released this 2026-10-21 13:33:44 +00:00 | 37 commits to master since this release

    Fixed

    • The admin pages fit a phone. At 390 px, Activity, Clients, Diagnostics and every configuration table scrolled sideways, and Diagnostics and Clients made the whole page 826 px and 660 px wide, so the phone zoomed out. A table now shows all its columns only where they fit without wrapping. In a narrower table, the first cell carries the other columns' facts on short lines ("Priority 20 · TLS name dns.quad9.net", "Created 19 Oct 2026, 16:15:44"), and long names, URLs, IPv6 addresses and patterns wrap instead of widening the page. In the narrow Sources and Upstreams tables, Edit and Delete stack, which gives the first cell the width. Protection > Sources needs a 1440 px wide table for all its columns, so a 1440 px window now shows its narrow form; in 0.0.23 it made the page 1557 px wide there.
    • Overview is no longer taller than the window. The charts' screen-reader tables extended the document below the app, so the page had a second scroll bar under the main one at desktop widths.
    • The Diagnostics count line no longer spreads its words across the page.
    • The Diagnostics health cards no longer spread a short card's lines down its height.

    Artifacts

    5710eaf9488e58f3b85b2870760932d57d10540a9e0e002a0fb29ea9b4cb389f  nxdns-0.0.24-x86_64-linux-musl.tar.gz
    9ec8c5b6c1655091e9dc0263edc72b5e6801ab540adad440be67687de4ea7361  nxdns-0.0.24-aarch64-linux-musl.tar.gz
    831a4bc50572241d0818a9716d955ae3bf2ae4a70b60349abb593e9512861e26  IMAGE-DIGEST.txt
    
    git.mial.net/mokhtar/nxdns:0.0.24@sha256:9f2b2253c840f2e908218d6338b74e5bc748873b6a543750130bbb9cea7fb0af
    

    Compare v0.0.23...v0.0.24

    Commits since v0.0.23
    77ae1a1 ci: limit the frontend job to 8 minutes
    a0d8af3 build: bump version to 0.0.24
    3e8cd0e changelog: date the 0.0.24 section
    f26ee52 admin: tables fit a phone, their first cell carrying the hidden columns, and no positioned label widens the page
    
    Downloads
  • v0.0.23
    Gates / package (push) Successful in 47s
    Gates / container (push) Successful in 11s
    Release / gates (push) Successful in 12m3s
    Release / publish (push) Successful in 5m25s
    Gates / frontend (push) Successful in 2m15s
    Gates / test (push) Successful in 2m47s
    Gates / test-aarch64 (push) Successful in 8m28s
    Gates / package (push) Successful in 6m36s
    Gates / container (push) Successful in 16s
    CI / gates (push) Successful in 18m14s
    Release / guard (push) Successful in 41s
    Gates / frontend (push) Successful in 3m5s
    Gates / test (push) Successful in 3m19s
    Gates / test-aarch64 (push) Successful in 7m45s
    Stable

    mokhtar released this 2026-10-20 13:57:09 +00:00 | 41 commits to master since this release

    Fixed

    • A blackhole route to an upstream no longer stops failover. On a route like that, connect() fails with an errno the runtime has no name for, and nxdns took it for a fault of its own: the query got SERVFAIL at once, the next upstream was never tried, and nothing was charged to the unreachable one. A connect failure of that kind now counts against that upstream as ConnectFailed (cause Unexpected), and the query fails over.
    • The Overview charts no longer draw the current bucket as a fall in traffic. Every Overview window ends at the end of the bucket that holds the present moment, so its last bucket is still counting. Queries over time draws the curve into it dashed over a fainter fill, and Client activity draws its column faint inside a dashed outline. Both legends name "Still counting", and the tooltip and the chart's data table give that bucket's time as "
    • The query detail page names the device. The Client fact showed only the address, while the Activity list showed "iPhone (192.168.50.52)" for the same query. It now uses the list's label. The query log records only the address, so the record's intro says the device name is the one the address has today.

    Added

    • A NixOS module. The flake exports nixosModules.default, which adds services.nxdns with four options: enable, package, configFile and openFirewall. It runs the release's own nxdns.service with a drop-in for file mode, checks configFile with the pinned binary's nxdns import at build time so a configuration that does not parse, validate or reconcile fails the build, and restarts the service when only the configuration changes. The flake's package now also installs lib/systemd/system/nxdns.service. See "Install nxdns with Nix".
    • nxdns_upstream_local_resource_total counts exchanges that ended on this process's own resources (memory, file descriptors, an unnamed system error) before any upstream answered. Until now, such a SERVFAIL left no record of its cause anywhere.

    Changed

    • The compose file names its own release. deploy/docker/compose.yaml defaults its image to the release it is tagged with instead of :latest, so docker compose up -d with the file from a tag runs that tag's image, and the install and upgrade steps no longer set NXDNS_VERSION. The variable still picks another release, and NXDNS_IMAGE still names a local image. Compose files from v0.0.22 and earlier keep the :latest default.
    • A DoH upstream that answers with an error status says which. The Diagnostics episode and /api/health read HttpStatus (status 505 HTTP Version Not Supported) instead of HttpStatus (cause HttpStatus). A 505 is a server that requires HTTP/2, which nxdns does not speak.

    Artifacts

    255ffa81b09cd84c25e92c699c3b8be59ea2bc287accdca62ed81f5219d852af  nxdns-0.0.23-x86_64-linux-musl.tar.gz
    563be323c6ef1601c3a547233aa70dcacc384507210aa54d2c7efcf833148055  nxdns-0.0.23-aarch64-linux-musl.tar.gz
    a680d2fc13ca7723d006c888a82ee10acf7d83f541d6c74deeac0d29993bb87b  IMAGE-DIGEST.txt
    
    git.mial.net/mokhtar/nxdns:0.0.23@sha256:7a554696b9649c92e2ead85ebf8a04ce37339ed68e8fe3452f2d3f8bcc3994d1
    

    Compare v0.0.22...v0.0.23

    Commits since v0.0.22
    9a99890 build: bump version to 0.0.23
    4ad7ad6 changelog: date the 0.0.23 section
    b4ef7b8 website: plan records the approved look, three install tabs and phone screenshots
    d9d1c1d docs: verify-a-release transcripts elide the signing key's email address
    f351469 nix: a services.nxdns module that runs the packaged unit in file mode against a configuration the pinned binary accepted
    aa8c9e2 deploy: the compose file names its own release, and the cut moves it with the version
    ea9f16a admin: the overview's last bucket is drawn as still counting; the query detail names the device as the activity list does
    8efe504 upstream: an unnamed connect errno fails over, local-resource exchanges are counted, doh faults carry the http status
    2697adf website: demo household and the admin screenshots it produced
    4ef795a docs: config examples use cloudflare doh; quad9 doh needs http/2 and answers 505
    
    Downloads
  • v0.0.22
    Gates / package (push) Successful in 7m56s
    Gates / frontend (push) Successful in 3m15s
    Gates / test (push) Successful in 4m4s
    Gates / test-aarch64 (push) Successful in 10m25s
    Gates / container (push) Successful in 17s
    CI / gates (push) Successful in 22m50s
    Release / guard (push) Successful in 38s
    Gates / test (push) Successful in 2m22s
    Gates / frontend (push) Successful in 2m25s
    Gates / test-aarch64 (push) Successful in 7m37s
    Gates / package (push) Successful in 50s
    Gates / container (push) Successful in 14s
    Release / gates (push) Successful in 11m6s
    Release / publish (push) Successful in 10m2s
    Stable

    mokhtar released this 2026-10-20 06:10:01 +00:00 | 51 commits to master since this release

    Added

    • /metrics reports the most concurrent work the server has seen. Five gauges hold peaks since start: nxdns_dns_in_flight_peak (queries handled at once, every listener together), nxdns_tcp_server_connections_peak, nxdns_dot_server_connections_peak and nxdns_doh_server_connections_peak (connections one listener held at once), and nxdns_querylog_queue_peak (entries waiting for the query log writer at once). The memory budget work sizes its limits from them; "Measure performance" shows how to read them beside the process's resident memory, thread count and worker stacks.

    Artifacts

    8b9aefceced0e6fb361e4a670ba1fb7a5d4527b00f1f0212ef06d6ff90c20bcd  nxdns-0.0.22-x86_64-linux-musl.tar.gz
    5f386a31acdd7f8619c9349be8a491b896712d9506b2affb67d7247b3ed9c5c0  nxdns-0.0.22-aarch64-linux-musl.tar.gz
    c2eff16e9169d1f66b8a2883b2d9e3a2a986f9f0b5c28ad454894ec849a65e82  IMAGE-DIGEST.txt
    
    git.mial.net/mokhtar/nxdns:0.0.22@sha256:4c9f705af5fdb23656f585ede3a4935e2924e28b6d01d275d6c63eafa2acab7d
    

    Compare v0.0.21...v0.0.22

    Commits since v0.0.21
    0385c34 build: bump version to 0.0.22
    36e11ca metrics: peak gauges for in-flight queries, stream connections and the query log queue
    9d2511e specs: memory budget, measured owners and the fix order
    cab79c7 plan: nxdns.sh landing page settled; doq waits on a quic stack, dnscrypt is out
    5acfec2 docs: the reproducibility gate exists since 0.0.17; a fresh rebuild of v0.0.21 matches
    534c620 docs: the install guides ran against the published v0.0.21, no more no-release notes
    
    Downloads
  • v0.0.21
    Gates / frontend (push) Successful in 2m1s
    Gates / test (push) Successful in 2m25s
    Gates / test-aarch64 (push) Successful in 8m19s
    Gates / package (push) Successful in 4m22s
    Gates / container (push) Successful in 12s
    CI / gates (push) Successful in 28m50s
    Release / guard (push) Successful in 35s
    Gates / frontend (push) Successful in 1m57s
    Gates / test (push) Successful in 2m24s
    Gates / test-aarch64 (push) Successful in 7m38s
    Gates / package (push) Successful in 54s
    Gates / container (push) Successful in 18s
    Release / gates (push) Successful in 11m18s
    Release / publish (push) Successful in 4m56s
    Stable

    mokhtar released this 2026-09-12 19:12:55 +00:00 | 57 commits to master since this release

    Changed

    • An upstream warning means the pool stopped trusting the endpoint. A Diagnostics episode opens when an upstream reaches the health failure threshold and closes on the success that clears it, instead of one card per lost exchange. Failures during backoff raise the card's occurrence count. The episode detail and the nxdns check report name the concrete cause behind the classification, SendFailed (cause BrokenPipe).

    Artifacts

    26615c4b52cbc1e60468bc40849be025b4214caa5a2b7dcde0a86da7cab3b4ce  nxdns-0.0.21-x86_64-linux-musl.tar.gz
    29746c9a68b7c07c1f89be216b6ba59a750f7d67767781482b100558567f19af  nxdns-0.0.21-aarch64-linux-musl.tar.gz
    d7f0f99e80b7cdd1c621235a2ccb8f1ab9537e25728a69beb9da63e2b97e2f32  IMAGE-DIGEST.txt
    
    git.mial.net/mokhtar/nxdns:0.0.21@sha256:ce1fef32c7ee6c23656abd94e53e4d4d6b1d34fe88a2c842b82c7202d8b904c3
    

    Compare v0.0.20...v0.0.21

    Commits since v0.0.20
    f2dd6ad build: bump version to 0.0.21
    08cdf86 upstream: a diagnostics episode follows health, and a peer fault carries its cause
    
    Downloads
  • v0.0.20
    Gates / frontend (push) Successful in 1m52s
    Gates / test (push) Successful in 2m22s
    Gates / test-aarch64 (push) Successful in 8m10s
    Gates / package (push) Successful in 4m22s
    Gates / container (push) Successful in 10s
    CI / gates (push) Successful in 28m22s
    Release / guard (push) Successful in 35s
    Gates / frontend (push) Successful in 1m53s
    Gates / test (push) Successful in 2m20s
    Gates / test-aarch64 (push) Successful in 7m26s
    Gates / package (push) Successful in 51s
    Gates / container (push) Successful in 11s
    Release / gates (push) Successful in 10m52s
    Release / publish (push) Successful in 4m56s
    Stable

    mokhtar released this 2026-09-12 13:55:06 +00:00 | 59 commits to master since this release

    Fixed

    • A blocklist source no longer fails on a stale pooled connection. The fetcher reused a keep-alive connection from an earlier pass that the server had closed, and the standard client never retries one; every later download from that host failed with HttpConnectionClosing at 0 ms. Downloads now send connection: close and never enter the pool.

    Artifacts

    ae74e98e8ec9f6e63ea48371278660c1ba94ec4da8ecdd20afdcfb551850899d  nxdns-0.0.20-x86_64-linux-musl.tar.gz
    da9f3a148983822e120c3ce657ac34aa4ae4a7d76d0d1ca2fd930e67c580126e  nxdns-0.0.20-aarch64-linux-musl.tar.gz
    80ded73a588da1dc90cd38c6202f13fb3fd7bcd73b9cd1f9cf545601dc9bdd3d  IMAGE-DIGEST.txt
    
    git.mial.net/mokhtar/nxdns:0.0.20@sha256:955379672493f64b59ed3f18899fb0808197492e2abd0eedcaa6c6ec6d1f3258
    

    Compare v0.0.19...v0.0.20

    Commits since v0.0.19
    6e9a369 build: bump version to 0.0.20
    f6fa43a filter: blocklist downloads never reuse a pooled connection, the peer closes it between passes
    
    Downloads
  • v0.0.19
    Gates / frontend (push) Successful in 2m3s
    Gates / test (push) Successful in 2m33s
    Gates / test-aarch64 (push) Successful in 8m14s
    Gates / package (push) Successful in 52s
    Gates / container (push) Successful in 14s
    CI / gates (push) Successful in 12m0s
    Release / guard (push) Successful in 33s
    Gates / frontend (push) Successful in 2m36s
    Gates / test (push) Successful in 3m47s
    Gates / test-aarch64 (push) Successful in 7m24s
    Gates / package (push) Successful in 50s
    Gates / container (push) Successful in 15s
    Release / gates (push) Successful in 12m19s
    Release / publish (push) Successful in 6m37s
    Stable

    mokhtar released this 2026-09-12 09:14:36 +00:00 | 61 commits to master since this release

    Changed

    • A failed blocklist download says why. The warning line and the Diagnostics event detail now carry the phase that failed, the concrete cause behind the classification (a reset connection, a truncated chunk, a TLS handshake fault), the HTTP status if a head arrived, the bytes received, and the elapsed time. The separate http status warning is folded into that line. Same one line per failed source per pass as before.

    Artifacts

    4af595f259b225671e54186e00eb6574c6f0180f212f1fe9b8955d6b6b74b028  nxdns-0.0.19-x86_64-linux-musl.tar.gz
    b0d223b272794cf469484ff00edc1bd23ee5632c8c5c23ccc1cec802fe6ccb7b  nxdns-0.0.19-aarch64-linux-musl.tar.gz
    b1afe29eed90b2e87e7fd603ea8e6e6478d96946861151efbd3275adf0ff4fe3  IMAGE-DIGEST.txt
    
    git.mial.net/mokhtar/nxdns:0.0.19@sha256:b80023379b012db3898d78f716a5e6c6967459416252f528cc207cffae44b0e5
    

    Compare v0.0.18...v0.0.19

    Commits since v0.0.18
    f4562ca filter: skip the read-only directory test as root, ci's runner ignores mode bits
    250bdca build: bump version to 0.0.19
    63f4f96 changelog: date the 0.0.19 section
    5215819 filter: a failed blocklist download names its phase, cause, status, bytes and elapsed time
    bf79a22 docs: renovate's nix manager does not bump a tag ref; the regex manager recipe that does
    
    Downloads