-
v0.0.13
StableGates / frontend (push) Successful in 1m35sGates / test (push) Successful in 2m23sGates / test-aarch64 (push) Successful in 8m13sGates / package (push) Successful in 4m15sGates / container (push) Successful in 10sCI / gates (push) Successful in 23m19sRelease / guard (push) Successful in 34sGates / frontend (push) Successful in 1m39sGates / test (push) Successful in 2m19sGates / test-aarch64 (push) Successful in 7m25sGates / package (push) Successful in 48sRelease / publish (push) Successful in 6m36sGates / container (push) Successful in 17sRelease / gates (push) Successful in 10m52sreleased this
2026-08-27 20:36:04 +00:00 | 0 commits to master since this releaseThe upstream query budget becomes one honest deadline. A busy network no longer blames a healthy standby for running out of time, and a query burst no longer queues invisibly until everything answers SERVFAIL at once.
Fixed
- The per-query upstream budget is now one absolute deadline, spent by everything that blocks. Waiting for a free slot on a saturated upstream now spends the query's
upstream.total_timeout_msbudget just like the exchange itself, instead of being invisible to it — under a burst, queries used to wait out their whole budget in the queue and then start attempts they could never finish. An attempt near the end of the budget runs truncated, and when a truncated attempt runs out of time that is evidence about the budget, not the upstream: it no longer counts against that upstream's health or success rate, and the query log no longer names an upstream that was given no fair chance. A field incident produced 279 rows blaming a standby whose health counters read zero for zero; those rows now attribute nothing. - A query no longer blocks behind a saturated upstream while another has capacity. Admission sweeps the upstreams in priority order and takes the first free slot; priority now means the order among upstreams that can be admitted right now, and a query blocks only when nothing has capacity — on the highest-priority eligible upstream, bounded by the remaining budget.
- Conditional forward zones spend
upstream.read_timeout_msonce per query. A UDP attempt, a truncated answer and the TCP retry now share the one budget instead of taking a fresh one each, so a slow zone resolver can no longer stretch a single query to several times the configured timeout.
Added
nxdns_upstream_budget_exhausted_total. A pool-wide counter of queries whose budget ran out — in the queue or mid-attempt — before any upstream answered. It carries no per-upstream label on purpose: running out of budget is a fact about the pool.- A configuration with more than 64 enabled upstreams is rejected at validation with a clear message, instead of tripping an internal limit at startup.
Artifacts
fa71dca32187e7604de0c7db5c2b710b99a26d5072b5ddd6b10d46ba4f8d6976 nxdns-0.0.13-x86_64-linux-musl.tar.gz e821383e483f351ee8e70a2d6d271c6737c0ea7dfa9b3723270a67ee6747fe60 nxdns-0.0.13-aarch64-linux-musl.tar.gz 9130dacb4c4be48ed1a981fd32f4f9622a1d04b97fe4862c64413dc299df32b7 IMAGE-DIGEST.txtgit.mial.net/mokhtar/nxdns:0.0.13@sha256:567fa7e1e0f92c0d4d92e756a0043e5be0ee3442e08cad6e340be489f6912ce0Commits since v0.0.12
c9701fa build: bump version to 0.0.13 a3aa7fe upstream: one absolute per-query budget across queueing and failoverDownloads
- The per-query upstream budget is now one absolute deadline, spent by everything that blocks. Waiting for a free slot on a saturated upstream now spends the query's