Why does ping wait 1 second for the next ping?
On Ubuntu 20.04.4 I am running a
ping command like
sudo ping -l 2000 -c 200 domain.com
and it does the first 12 pings immediately, but then only 1 ping after the other ping with a delay of 1 second.
To be precise: I get an output like this
64 bytes from my.domain.com (126.96.36.199): icmp_seq=65 ttl=62 time=0.392 ms 64 bytes from my.domain.com (188.8.131.52): icmp_seq=66 ttl=62 time=0.398 ms
and each line (
icmp_seq) is one second apart. So for the 200 pings to complete I have to wait approx. 200 seconds.
I noticed that when I run the command on
localhost or on a Mac all the 200 pings run within a second, without the wait between the individual pings.
What is the reason for this behavior? Is there any way to run the ping command faster?
What is the reason for this behavior?
The basic issue with ping speed is that it may flood any connection and cause a DOS over that connection. To ease (avoid) such problem,
ping is limited to produce (send) one packet per second by default.
-l option is not meant to control the time it takes for packets to be sent. It is used to preLoad the network. I.e.: it is the number of packets that would be sent to the network initially without waiting for a reply. After that, the default time of 1-second is used to sent packets for each (detected) packet received back (response). However that preLoad is limited for normal users. The number of preloaded packets is limited to 3 for a normal user. With iputils-ping version
20210202 we can add a
-D to see the time of each packet sent:
$ sudo ping -c 5 -l 3 -D 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. [1655501483.063447] 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.134 ms [1655501483.063488] 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.019 ms [1655501483.063510] 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.017 ms [1655501484.094896] 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.156 ms [1655501485.065238] 64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.153 ms --- 127.0.0.1 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 0.017/0.095/0.156/0.063 ms, pipe 3
Which shows that only 3 packets are sent ASAP and the rest waits 1 second.
That’s using the local address
127.0.0.1. Which is the fastest address that could be used, as it is entirely local.
Resolving some other address, or even worse, a domain, may introduce additional delays.
A preload of 2000 over 200 packets would preload all of them leading to no delay in sending and only the delay of the answer will matter.
Is there any way to run the ping command faster?
But all the above is not the correct way to control the speed at which packets are sent.
For that there are the two options
$ sudo ping -D -c 5 -i 0.2 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. [1655501954.082366] 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.131 ms [1655501954.286594] 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.151 ms [1655501954.490564] 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.127 ms [1655501954.694608] 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.147 ms [1655501954.898607] 64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.151 ms --- 127.0.0.1 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 816ms rtt min/avg/max/mdev = 0.127/0.141/0.151/0.010 ms
That is a constant speed ping command. Note that even for the local address it takes a bit more than 0.13 ms to get a response. As a general rule, pinging with times lower than 0.1 seconds is not recommended.
And the option
-f which is used exactly to flood the network as fast as possible. But which will certainly block any other process using it.
In fact, the question should be: why do you want a fast ping?.
Just to have the fastest answer?
That is not really useful as the intent of
ping is to test the network over some period of time, a reasonable period of time, to ensure that the network is stable and useful. A "too fast" test will test the network at only one point in time (in which the network is working) but will fail to detect problems over time (the network might fail). Besides, it affects other users of the same network. If you want a "one time only" test, then use the
-c count option combined with the
-w delay option which will end after either count packets have been received or delay has been elapsed:
$ sudo ping -D -c 3 -w 5 example.com ; echo "$?" $ sudo ping -D -c 3 -w 5 examples.com ; echo "$?"
The first one will count 3 packets and exit successfully.
The second one will fail after 5 seconds.
That is one correct way to test connectivity.