Technical overview
How a question is answered
One synchronous, allocation-free fast path per CPU core. Anything that has to wait goes async.
Threads
Every core on its own
Each worker thread owns a SO_REUSEPORT socket, so the kernel spreads clients across cores with no shared queue. Workers meet only at the cache, which is split into 64+ independently locked shards. Cache misses, TCP, DoT, and DoH run on a small async runtime.
Measured: 3.58× throughput going from 1 to 4 workers.
Cache
Store the reply, patch the bytes
Instead of decoding and re-encoding, TelltaleDNS keeps the upstream's reply as raw bytes and remembers where each TTL lives. A hit is a copy plus a handful of small writes.
Upstreams
Hedged, not hopeful
If an upstream hasn't answered within about 3× its usual time, the next one is asked in parallel. The first good answer wins. A server that fails three times in a row is benched, then probed again later, and probes never make a client wait.
With one of two upstreams completely dead: 0 failed queries, and p99 within 1.04–1.15× of normal.
Blocking
Blocking you can explain
Hosts files, AdBlock-style lists, and Pi-hole regexes are compiled in the background into one compact snapshot: about 9 bytes per blocked name, and a lookup takes under a microsecond. A new snapshot replaces the old one atomically, without pausing a query, and a recompile under load left p99 latency unchanged in our tests.
Every decision names its rule. telltale explain shows who a device is, its groups, every rule in every list that matches (with its line number), and which one decides.
Query log
Every query, searchable in a second
Each answer leaves a record: device, name, outcome, the rule that decided, and timings. The records are stored as one compressed file per hour, about 14 bytes per query, written in large sequential batches that are kind to SD cards. If the disk falls behind, records are dropped and counted; answers never wait for the log.
A search looks at each hour's list of names before it touches any rows, and skips hours that can't match. On a Raspberry Pi 4, finding a rare name among 50 million queries from the last 30 days takes about 0.2 s. Searches run at the lowest CPU priority, so DNS always comes first.
Sign-in
Locked until you set it up
There is no default password. On first start TelltaleDNS creates a one-time setup token, readable only by its own user, and whoever has it creates the first admin. Kubernetes and Ansible installs can create that admin from a secret instead.
The web UI is part of the binary, about 90 KiB compressed: a dashboard, a searchable query log with a "Why?" button on every row and a live view that streams queries as they happen, and pages for lists, devices and groups, upstreams, names on your network, the cluster, users, and API tokens. It follows your light or dark theme and works on a phone. Charts reach back 400 days from a small on-disk history, and a ready-made Grafana dashboard covers the Prometheus metrics.
People sign in with a password and, if they like, an authenticator app, or with the identity provider they already use (Keycloak, Authentik, any OpenID Connect provider), which also decides their role. Scripts, dashboards, and AI agents get their own tokens, limited to reading if that is all they need. Prometheus and home dashboards can use HTTP Basic, but only for accounts where an admin turned it on. Each user is a viewer, an operator, or an admin, and every change they make lands in a tamper-evident audit log.
Clustering
One cluster across a Pi and Kubernetes
Also built in
The rest of the toolbox
DNSSEC
Validates signatures itself, with negative trust anchors for broken domains, and says why a lookup failed (extended DNS errors).
Serve-stale and prefetch
Popular names are refreshed before they expire, expired answers keep flowing while upstreams are down, and the cache survives a restart.
Encrypted DNS for devices
DNS over TLS and HTTPS listeners with certificates reloaded on the fly, and PROXY protocol v2 so a load balancer doesn't hide clients.
Moving in
telltale import pihole reads a Teleporter export; telltale import technitium reads a live server. Both write a config file with notes on what didn't carry over.
Backups
One .ttbk archive with your configuration, users, devices, audit log, and statistics history (the query log optional), checksummed so a restore verifies every file before it writes any.
AI agents
Agent tokens with narrow scopes, a reason on every change, rate limits, and a kill switch. An MCP server (/mcp) gives assistants tools to look around and to plan changes, which take effect only when applied, and only after you approve them if you want that.
Versions and updates
Every build knows its version and commit, checks a signed release index daily (optional), and tells you how to update for the way you installed it.
Anomalies
Learns each device's normal pattern and points out query spikes, bursts of new domains, and regular phone-home beacons, with the evidence. Findings never block anything on their own.