DNS lookup duration and uptime monitoring

I recently had a bit of trouble with really slow page loads in my browser which I couldn’t correlate with network packet loss or slow pings. I think it was related slow DNS lookup times (through NextDNS) although I’m not 100% sure because by the time I figured out how to diagnose DNS, the problem had gone away.

Anyway I came up with this command line monitor for DNS lookup times and figured it might be useful for others so sharing here and also looking for feedback on the approach I’ve used.

The following command monitors the DNS query time. If the DNS query fails it results in a value of -10. This is partly to drive the uptime monitoring (see next template configuration), but also makes it easy to spot outages when charting query times. The default scan interval for a command line sensor is 60 seconds, so the domain name used needs to use a TTL less than 60 seconds, otherwise the DNS lookup will be cached by the DNS resolver. I’ve used force.com which has a 30s TTL.

- platform: command_line
  name: DNS resolution time
  command: "dig +retries=1 force.com | grep -A 100 'ANSWER SECTION:' | grep -Po '(?<=Query time: )[0-9a]*' || echo '-10'"
  unit_of_measurement: "mS"

And then this uses the sensor result to track DNS uptime (i.e. is DNS resolving)

template:
  - binary_sensor:
      - name: DNS Resolution
        state: >
          {{ states('sensor.dns_resolution_time') != "-10" }}


4 Likes

It’s good.
I use Uptime-Kuma which I would like to see added to the official addons, because it’s very useful. And has built in realtime alerting.

uptime-kuma looks cool, does it use dig to test DNS speed?

1 Like

I’m not sure if the latency it returns is via DIG, or if it is a ping response. Whatever the case, it returns a latency, and marks the service as down if the query could not be resolved.

This is awesome and totally works, thanks for sharing it. I’d like to quickly add that if you want statistics to be recorded for your new command line sensor, you need to include the state_class: measurement for the sensor in your customize yaml. :+1:

This is what’s working for me on HA Core 2025.5.3 using only awk.

sensor:
  - platform: command_line
    name: "DNS Resolution Time"
    command: >
      dig +timeout=1 +tries=1 force.com | awk '
        /ANSWER SECTION:/ { 
          found_answer_section = 1; 
          next 
        } 
        found_answer_section { 
          if (/Query time:/) { 
            print $4; 
            exit 
          } 
        } 
        END { 
          if (NR == 0 || !found_answer_section) { 
            print "-10"; 
            exit 1 
          } 
        }'
    unit_of_measurement: "ms"
    state_class: measurement
    scan_interval: 300

template:
  - binary_sensor:
      - name: "DNS Resolution"
        state: >
          {{ states('sensor.dns_resolution_time')|int(-10) != -10 }}
        device_class: connectivity