DNS Caching Behavior in Deno
Deno does not provide a programmatic API to manually flush or invalidate the DNS cache at runtime. DNS resolution is handled by the underlying Rust networking stack (the tokio/hickory-resolver ecosystem), which is designed to respect the Time-to-Live (TTL) values provided by the DNS server. In a standard environment, a long-running Deno process will refresh its IP mapping once the TTL expires. If you are seeing entries persist beyond their TTL, the cause is almost certainly outside Deno's resolver itself.
Likely Causes of Stale Entries
Confirmed facts are limited here: Deno delegates resolution to native code, and the exact cache behavior is not consistently documented across Deno 1.x and 2.x releases, so version-specific TTL differences cannot be stated with certainty. The likely explanations for stale entries are these architectural layers:
- OS-Level Caching: Many operating systems (particularly Windows and macOS) run their own DNS caching services. If the OS returns a cached entry regardless of TTL, Deno will use it.
- Application-Level Caching: Third-party HTTP client modules may implement their own DNS caching or connection pooling that ignores standard TTLs, independent of Deno's permission model.
- Connection Keep-Alive: In long-running servers, persistent TCP connections remain bound to the original IP. Even after DNS refreshes, existing sockets keep routing to the old address until they close. This is the most common cause of apparent "stale DNS" during failover or load-balancer rotation.
Verification Steps
- Isolate the resolver: Run
dig example.com or nslookup example.com on the same machine. If these return the stale IP, the issue is at the OS or network level, not Deno.
- Test with a low TTL: Point a test record at a low TTL (e.g., 60 seconds), change the target, and log which IP your Deno process connects to over time. Compare against
dig output in the same window.
- Check connection reuse: If you use a custom
fetch wrapper or agent, verify you are not holding persistent connections that predate the DNS change. Forcing new connections (or restarting the process) should pick up the new IP immediately if DNS is healthy.
Practical Mitigation
Since there is no flush API, the reliable mitigations are: keep TTLs short on records behind failover, bound connection lifetimes in your HTTP client so sockets are re-established periodically, and restart workers on a schedule or via orchestration health checks when an IP change is detected. Treat any claim about exact cache duration in a specific Deno version as unverified until tested against your deployment.
One diagnostic detail that changes the recommendation: are you using the standard fetch API or a third-party networking library? That determines whether the caching lives in the native Rust layer or a JavaScript wrapper with its own rules.