Understanding and Optimizing DNS Caching in dnsmasq: TTL Behavior and Performance Tuning


3 views

dnsmasq implements DNS caching by honoring the TTL (Time-To-Live) values returned by authoritative DNS servers. Unlike some caching resolvers that impose fixed cache durations, dnsmasq primarily relies on these TTL values while providing configuration flexibility.

The cache behavior can be observed in your dig output where TTL=181 seconds (3 minutes) appears for api.mch.weixin.qq.com. This means:

  • The record will be cached for exactly 181 seconds after the first query
  • Subsequent queries will return the cached record while decrementing the TTL
  • After expiration, the next query will trigger fresh DNS resolution

You can control caching through these dnsmasq.conf parameters:

# Set minimum TTL (overrides server TTL if lower)
min-cache-ttl=60

# Set maximum cache time (caps excessive TTLs)
max-cache-ttl=3600

# Negative caching (failed lookups)
neg-ttl=60

# Preload frequently used records
address=/api.example.com/192.168.1.100

For your specific case with intermittent 5-10 second lookups:

# Recommended settings for unstable DNS:
min-cache-ttl=300      # 5 minute minimum cache
max-cache-ttl=1800     # 30 minute maximum cache
no-resolv              # Use predefined servers
server=8.8.8.8         # Fast backup resolver
server=1.1.1.1         # Secondary backup

Use these commands to verify cache behavior:

# Check cache hits vs misses
sudo grep 'query\\|cached' /var/log/syslog

# View current cache contents
sudo kill -SIGUSR1 $(pidof dnsmasq)
sudo tail -f /var/log/syslog

For scripted monitoring, consider this Python example:

import subprocess
import time

def check_dns_performance(domain):
    start = time.time()
    subprocess.run(['dig', '+short', domain], check=True)
    return time.time() - start

# Continuous monitoring
while True:
    latency = check_dns_performance('api.mch.weixin.qq.com')
    if latency > 1.0:  # Threshold in seconds
        print(f"High latency detected: {latency:.2f}s")
    time.sleep(60)

For mission-critical services, implement prefetching before TTL expires:

# dnsmasq 2.80+ supports prefetching
prefetch
prefetch-keyword=api.mch.weixin.qq.com

Combine with a cron job to maintain warm cache:

*/2 * * * * dig api.mch.weixin.qq.com >/dev/null 2>&1

When slow lookups persist:

  1. Verify upstream DNS server performance with dig @8.8.8.8 api.mch.weixin.qq.com
  2. Check for DNSSEC validation overhead with dnssec-check-unsigned
  3. Test with cache disabled: dnsmasq --no-daemon --no-hosts --cache-size=0



When troubleshooting DNS lookup delays in dnsmasq (like the 5-10 second issue you're experiencing), we need to understand multiple layers of caching behavior:

dnsmasq doesn't have a fixed internal cache duration - it respects the TTL (Time To Live) values returned by authoritative DNS servers. However, there are key behaviors to note:

# Default minimum TTL (can override server TTL)
min-cache-ttl=0

# Maximum TTL (even if server returns higher)
max-cache-ttl=0 # 0 means no limit

Your second dig output shows the actual TTL situation:

;; ANSWER SECTION:
api.mch.weixin.qq.com.      181     IN      CNAME   forward.qq.com.
forward.qq.com.             181     IN      A       101.226.90.149

The 181 value is the remaining TTL in seconds (about 3 minutes). This explains why you're seeing intermittent slowdowns - when the cache expires, dnsmasq must perform fresh lookups.

For external services with fluctuating IPs but requiring performance, consider these adjustments:

# /etc/dnsmasq.conf
min-cache-ttl=300       # Minimum 5 minute cache
max-cache-ttl=3600      # Maximum 1 hour cache
neg-ttl=60              # Cache negative responses for 1 minute

For mission-critical services, combine caching with proactive DNS refreshing:

#!/bin/bash
# /etc/cron.hourly/refresh_dns
dig +short api.mch.weixin.qq.com > /dev/null

This keeps the cache warm while still respecting TTL boundaries.

Monitor cache hits/misses with:

dnsmasq --test --log-queries

And analyze with:

dig +trace api.mch.weixin.qq.com   # View full resolution path
dnsmasq --no-daemon --log-queries  # Real-time cache logging