cheat sheet
ping
Send ICMP echo requests to a host to test reachability, measure round-trip latency, and detect packet loss from the Windows command prompt.
ping — Test Network Connectivity
What it is
ping is a built-in Windows command that sends ICMP Echo Request packets to a target host and waits for ICMP Echo Reply packets in return. It reports round-trip time (RTT) per packet and summarises packet loss — the first tool to reach for when a network path is suspected to be broken. It does not diagnose where a path breaks (use tracert for that), but confirms basic reachability and latency in seconds.
Availability
ping ships as C:\Windows\System32\ping.exe on every Windows version. The Linux/macOS ping is a separate binary with different flag names (-c for count vs -n).
ping /?
Output:
Usage: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
[-r count] [-s count] [[-j host-list] | [-k host-list]]
[-w timeout] [-R] [-S srcaddr] [-c compartment] [-p]
[-4] [-6] target_name
Syntax
ping [options] target
Output: (ICMP echo statistics)
Essential options
| Switch | Meaning |
|---|---|
target | Hostname or IP address |
-n count | Number of echo requests to send (default 4) |
-t | Ping continuously until Ctrl+C |
-a | Resolve IP addresses to hostnames |
-l size | Packet payload size in bytes (default 32, max 65500) |
-w timeout | Timeout per reply in milliseconds (default 4000) |
-4 | Force IPv4 |
-6 | Force IPv6 |
-i TTL | Time-To-Live for outgoing packets |
-f | Set Don't Fragment bit (useful for MTU testing) |
Basic ping
Sending 4 ICMP requests (the default) confirms whether a host is reachable and shows RTT.
ping myhost
Output:
Pinging myhost [192.168.1.100] with 32 bytes of data:
Reply from 192.168.1.100: bytes=32 time<1ms TTL=128
Reply from 192.168.1.100: bytes=32 time<1ms TTL=128
Reply from 192.168.1.100: bytes=32 time<1ms TTL=128
Reply from 192.168.1.100: bytes=32 time<1ms TTL=128
Ping statistics for 192.168.1.100:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
ping 8.8.8.8
Output:
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=14ms TTL=117
Reply from 8.8.8.8: bytes=32 time=13ms TTL=117
Reply from 8.8.8.8: bytes=32 time=14ms TTL=117
Reply from 8.8.8.8: bytes=32 time=14ms TTL=117
Ping statistics for 8.8.8.8:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 13ms, Maximum = 14ms, Average = 13ms
Controlling the count (-n)
-n sets how many requests to send. Use a large count to observe latency variance or packet loss over time; use 1 for a quick one-shot check.
ping -n 1 192.168.1.1
Output:
Pinging 192.168.1.1 with 32 bytes of data:
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Ping statistics for 192.168.1.1:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
rem Monitor packet loss over 100 pings
ping -n 100 192.168.1.1
Output:
...
Ping statistics for 192.168.1.1:
Packets: Sent = 100, Received = 97, Lost = 3 (3% loss),
...
Continuous ping (-t)
-t pings indefinitely until interrupted with Ctrl+C. Pressing Ctrl+Break (not Ctrl+C) prints the running statistics without stopping.
ping -t 192.168.1.1
Output:
Pinging 192.168.1.1 with 32 bytes of data:
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
...
^C
Ping statistics for 192.168.1.1:
Packets: Sent = 12, Received = 12, Lost = 0 (0% loss),
...
Resolve IP to hostname (-a)
-a performs a reverse DNS lookup on the reply address and displays the resolved name alongside the IP.
ping -a 8.8.8.8 -n 1
Output:
Pinging dns.google [8.8.8.8] with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=14ms TTL=117
Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
...
Packet size and MTU testing (-l, -f)
-l size changes the payload from the default 32 bytes. Combined with -f (Don't Fragment), it lets you find the maximum MTU on a path: increase -l until you see "Packet needs to be fragmented".
ping -l 1472 -f 8.8.8.8 -n 1
Output:
Pinging 8.8.8.8 with 1472 bytes of data:
Reply from 8.8.8.8: bytes=1472 time=15ms TTL=117
...
ping -l 1473 -f 8.8.8.8 -n 1
Output:
Packet needs to be fragmented but DF set.
Forcing IPv4 or IPv6 (-4, -6)
When a hostname resolves to both A and AAAA records, ping may choose either. Use -4 or -6 to pin to a specific version.
ping -4 example.com -n 2
Output:
Pinging example.com [93.184.216.34] with 32 bytes of data:
...
ping -6 example.com -n 2
Output:
Pinging example.com [2606:2800:220:1:248:1893:25c8:1946] with 32 bytes of data:
...
Using ping exit codes in scripts
ping exits 0 on success, 1 on failure (all packets lost or host unreachable). Use errorlevel in batch scripts to branch on reachability.
ping -n 1 -w 1000 192.168.1.1 > NUL
if errorlevel 1 (
echo Gateway unreachable
) else (
echo Gateway OK
)
Output:
Gateway OK
Adjusting the interval (-w) and source address (-S)
-w controls how long ping waits for each individual reply before declaring the packet lost; it does not change how fast probes are sent (which is fixed at one per second). -S chooses which local IP appears as the source of the ICMP packet, which matters on multi-homed machines where routing alone would pick the wrong interface.
rem Tight 500 ms timeout for a LAN healthcheck (fail fast)
ping -n 3 -w 500 192.168.1.1
Output:
Pinging 192.168.1.1 with 32 bytes of data:
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Ping statistics for 192.168.1.1:
Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
rem Force the ping to leave via the 10.0.0.5 interface
ping -S 10.0.0.5 -n 2 10.0.0.1
Output:
Pinging 10.0.0.1 from 10.0.0.5 with 32 bytes of data:
Reply from 10.0.0.1: bytes=32 time=1ms TTL=64
Reply from 10.0.0.1: bytes=32 time=1ms TTL=64
TTL inspection and OS fingerprinting
Each Reply line ends with TTL=N, which is the remaining TTL when the packet arrived. The original TTL is operating-system specific — Windows starts at 128, Linux at 64, some network appliances at 255 — and the number of intermediate routers is originalTTL - replyTTL. Use this to estimate hop count and identify the remote OS without running tracert.
ping -n 1 8.8.8.8
Output:
Reply from 8.8.8.8: bytes=32 time=14ms TTL=117
A TTL of 117 from a destination whose OS uses 128 as the initial TTL means the packet crossed 11 routers; if the destination uses 64, it would mean -53 hops (impossible), so 128 is the correct anchor here. Linux destinations typically arrive with TTLs in the 50–60 range, embedded devices with 240+.
Setting outgoing TTL (-i) and ToS (-v)
-i TTL sets the initial TTL on outgoing packets, which makes ping behave like a one-hop traceroute when set to small values. -v TOS was historically the IPv4 Type-of-Service byte; on modern Windows it is recognised but the IETF deprecated raw ToS in favour of DSCP, so its effect on routing is limited.
rem TTL=1 — only the first-hop router will reply (with "TTL expired")
ping -i 1 -n 1 8.8.8.8
Output:
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 192.168.1.1: TTL expired in transit.
Ping statistics for 8.8.8.8:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
The reply comes from the first router on the path, identifying the next hop. Increment -i to probe further hops — exactly how tracert works internally.
MTU and Path MTU Discovery
The Maximum Transmission Unit (MTU) is the largest IP packet a link can carry without fragmentation. Ethernet defaults to 1500 bytes, PPPoE typically 1492, IPSec/VPN tunnels often 1400 or less. Path MTU is the smallest MTU on any link between source and destination. ping -l <payload> -f lets you probe it directly: the largest payload that gets through without "Packet needs to be fragmented" is the path MTU minus 28 (20 bytes IP header + 8 bytes ICMP header).
rem Find path MTU by binary search (manual)
ping -l 1472 -f 8.8.8.8 -n 1
ping -l 1400 -f 8.8.8.8 -n 1
ping -l 1450 -f 8.8.8.8 -n 1
Output:
Reply from 8.8.8.8: bytes=1472 time=15ms TTL=117
...
If 1472 succeeds, path MTU is at least 1500 (1472 + 28). If 1472 fails but 1450 works, path MTU is between 1478 and 1500 — narrow further.
The Test-NetConnection -Traceroute -Hops <n> cmdlet in PowerShell can also discover MTU automatically (via -DiagnoseRouting), and netsh interface ipv4 show subinterfaces reports the configured MTU per interface.
netsh interface ipv4 show subinterfaces
Output:
MTU MediaSenseState Bytes In Bytes Out Interface
------ --------------- --------- --------- -------------
1500 1 12345678 9876543 Ethernet
1400 1 234567 345678 VPN
Compartments (-c)
Windows network compartments are isolated routing namespaces, used for things like Hyper-V container hosts and Edge browser InPrivate sessions. -c <compartment> runs the ping inside a specific compartment, letting you test connectivity from inside a sandbox.
ping -c 1 -n 2 example.com
Output:
Pinging example.com [93.184.216.34] with 32 bytes of data:
Reply from 93.184.216.34: bytes=32 time=13ms TTL=58
...
List compartments with netsh interface ipv4 show compartments (Vista+).
Record route and timestamp (-r, -s)
The IPv4 Record Route option asks each router on the path to stamp its IP into the option header, returning up to nine addresses (the IP option field is limited to 40 bytes). The Timestamp option does the same with millisecond timestamps. Both are widely ignored or stripped by modern routers and firewalls, so the output is often blank — but on the rare cooperative path they reveal the forward and reverse path in a single packet.
ping -r 9 -n 1 8.8.8.8
Output:
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=14ms TTL=117
Route: 192.168.1.1 ->
10.0.0.1 ->
72.14.215.165 ->
8.8.8.8 ->
8.8.8.8 ->
72.14.215.165 ->
10.0.0.1 ->
192.168.1.1
ping -s 4 -n 1 192.168.1.1
Output:
Pinging 192.168.1.1 with 32 bytes of data:
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Timestamp: 192.168.1.100 : 23456789 ->
192.168.1.1 : 23456789
These options are most useful inside a controlled corporate network where the routers honour them.
PowerShell equivalent: Test-NetConnection
Test-NetConnection is PowerShell's modern replacement for ping — it does ICMP echo by default but also offers TCP port testing, route tracing, and DNS resolution in a single cmdlet. The output is a structured object, which is far easier to script against than parsing ping text.
# Basic ping equivalent
Test-NetConnection 8.8.8.8
# Quiet — returns $true/$false, ideal for if/else
Test-NetConnection 8.8.8.8 -InformationLevel Quiet
# TCP probe instead of ICMP (works through ICMP-blocking firewalls)
Test-NetConnection www.example.com -Port 443
# Full diagnostic: traceroute + MTU + route selection
Test-NetConnection 8.8.8.8 -DiagnoseRouting -InformationLevel Detailed
Output:
ComputerName : 8.8.8.8
RemoteAddress : 8.8.8.8
RemotePort : 443
InterfaceAlias : Ethernet
SourceAddress : 192.168.1.100
TcpTestSucceeded : True
The TCP form is especially valuable when corporate firewalls block ICMP but allow application traffic — Test-NetConnection -Port 443 is the de-facto Windows replacement for nc -zv host 443 from the Unix world.
ping in scripting: parsing latency
When you need only the latency number for graphing or alerting, parse the time= field with for /f (cmd) or a regex in PowerShell.
@echo off
for /f "tokens=5 delims==m " %%a in ('ping -n 1 8.8.8.8 ^| findstr "time="') do (
echo Latency to 8.8.8.8: %%a ms
)
Output:
Latency to 8.8.8.8: 14 ms
# PowerShell — cleaner, structured
$r = Test-Connection 8.8.8.8 -Count 1
"$($r.Address) latency: $($r.Latency) ms"
Output:
8.8.8.8 latency: 14 ms
Identifying ICMP error types
ping reports more than just success/fail. Each non-reply has a distinct meaning that points to a different layer of failure.
| Message | Meaning |
|---|---|
Reply from X: bytes=... | Normal ICMP Echo Reply |
Request timed out. | No reply within timeout — firewall, host down, or extreme latency |
Destination host unreachable. | Local routing has no path; check route PRINT |
Destination net unreachable. | A router sent ICMP type 3 code 0 — upstream routing problem |
TTL expired in transit. | Packet bounced inside the network and ran out of TTL |
Packet needs to be fragmented but DF set. | Path MTU smaller than -l payload |
General failure. | Driver/adapter problem or IP not configured |
Hardware error. | Cable unplugged or NIC offline |
Transmit failed. General failure. | Source interface is down or has no IP |
Each of these maps to an ICMP type/code on the wire — capture with pktmon if you need the raw bytes.
ICMPv6 specifics
When pinging an IPv6 address, Windows sends ICMPv6 Echo Request (type 128) instead of ICMPv4 type 8. The flags -4 and -6 choose the family explicitly; the link-local prefix fe80::/10 requires a scope ID (%InterfaceIndex).
ping -6 fe80::1a2b:3c4d:5e6f:7a8b%12 -n 2
Output:
Pinging fe80::1a2b:3c4d:5e6f:7a8b%12 with 32 bytes of data:
Reply from fe80::1a2b:3c4d:5e6f:7a8b%12: time<1ms
Reply from fe80::1a2b:3c4d:5e6f:7a8b%12: time<1ms
rem IPv6 multicast — ping all routers on the link
ping -6 ff02::2%12 -n 1
Output: (one Echo Reply per responding router on the local link)
ICMPv6 also uses Neighbor Discovery (replacing ARP), so the first ping to a never-contacted IPv6 address may show a slight delay while NDP resolves the link-layer address.
Firewall and rate-limit considerations
Many corporate and cloud firewalls deprioritise or rate-limit ICMP to protect against Smurf attacks and DoS amplification. AWS security groups block all ICMP by default. Azure NSGs allow it only with an explicit rule. Linux kernels rate-limit replies via net.ipv4.icmp_ratelimit and net.ipv4.icmp_msgs_per_sec. A host that drops your ICMP but responds to TCP/443 is healthy from the application's perspective; Test-NetConnection -Port is the more reliable health check.
To allow inbound ICMP through Windows Firewall:
# Enable ICMPv4 Echo Request inbound (Administrator)
New-NetFirewallRule -DisplayName "Allow ICMPv4 Echo Request" -Protocol ICMPv4 `
-IcmpType 8 -Direction Inbound -Action Allow
Output:
Name : {GUID}
DisplayName : Allow ICMPv4 Echo Request
...
Enabled : True
Common pitfalls
- Firewall blocks ICMP — "Request timed out" can mean the host is up but the firewall drops ICMP; try
tracert,Test-NetConnection -Port, or another TCP-based test. -nvs-c— Windows uses-n count; Linux/macOS use-c count. Don't mix them when writing cross-platform scripts.- Loopback always replies —
ping 127.0.0.1confirms the TCP/IP stack is loaded but proves nothing about network connectivity. Pinginglocalhostfollows the hosts file, not DNS. - Large
-lvalues need-ffor MTU tests — without-f, fragmentation hides the true MTU boundary. - Continuous
-tin a script — a script containingping -twill hang; use-n countin automated contexts. > NULto silence output — redirect toNULwhen you care only about the exit code and don't want ICMP lines polluting script output.-wis per-reply, not total —-w 1000 -n 100may take up to 100 s if every probe times out, not 1 s; use a script timeout if you need a hard upper bound.errorlevelis 1 when ANY packet is lost on some Windows versions — older builds return non-zero if even one of N packets fails; check theReceived = Nline for partial success.- TTL=0 packets are silently dropped —
ping -i 0is invalid; use 1 or higher. -aadds significant delay — reverse DNS may take 1–2 s per address; skip it when you already know the IP.- Cached results in scripts — DNS resolution in
pinghonours the local resolver cache, so a recentipconfig /flushdnsmay not be enough if Windows has cached the negative response. -l 0is valid — sends a 0-byte payload (28 bytes of IP+ICMP headers only); useful for testing whether absolutely tiny packets traverse the path.- IPv6 link-local without scope ID fails —
ping fe80::1returns "Destination host unreachable" unless you append%<ifindex>. -S srcaddrrequires the address to already be assigned — you cannot spoof a source IP that the local stack doesn't own.
Real-world recipes
Wait until a host is reachable before proceeding
@echo off
:wait
ping -n 1 -w 2000 192.168.1.100 > NUL
if errorlevel 1 (
echo Waiting for 192.168.1.100...
goto wait
)
echo Host is up. Continuing.
Output:
Waiting for 192.168.1.100...
Waiting for 192.168.1.100...
Host is up. Continuing.
Bulk-check a list of hosts
@echo off
for %%h in (192.168.1.1 192.168.1.100 8.8.8.8) do (
ping -n 1 -w 1000 %%h > NUL
if errorlevel 1 (echo %%h UNREACHABLE) else (echo %%h OK)
)
Output:
192.168.1.1 OK
192.168.1.100 OK
8.8.8.8 OK
Measure average latency to a server
ping -n 20 example.com | findstr "Average"
Output:
Minimum = 13ms, Maximum = 18ms, Average = 14ms
Continuous ping with timestamps
The bare ping does not include timestamps, which makes correlating loss with other events painful. Wrap it in PowerShell to prepend a wall-clock time to each reply.
ping -t 8.8.8.8 | ForEach-Object { "{0:HH:mm:ss} {1}" -f (Get-Date), $_ }
Output:
14:32:01 Pinging 8.8.8.8 with 32 bytes of data:
14:32:01 Reply from 8.8.8.8: bytes=32 time=14ms TTL=117
14:32:02 Reply from 8.8.8.8: bytes=32 time=15ms TTL=117
14:32:03 Request timed out.
14:32:04 Reply from 8.8.8.8: bytes=32 time=14ms TTL=117
TCP-based reachability with Test-NetConnection
When the target blocks ICMP but accepts TCP — typical of cloud-hosted services — use Test-NetConnection with the relevant port.
@(
@{Host='api.example.com'; Port=443},
@{Host='db.internal'; Port=1433},
@{Host='cache.internal'; Port=6379}
) | ForEach-Object {
$r = Test-NetConnection -ComputerName $_.Host -Port $_.Port `
-InformationLevel Quiet -WarningAction SilentlyContinue
"{0}:{1} {2}" -f $_.Host, $_.Port, ($(if($r){'OK'}else{'FAIL'}))
}
Output:
api.example.com:443 OK
db.internal:1433 FAIL
cache.internal:6379 OK
Latency dashboard with CSV logging
Sample latency every second and write to CSV — feed into Excel or Grafana for a 24-hour view.
$path = "C:\Logs\latency.csv"
"Timestamp,Target,LatencyMs" | Out-File -Encoding ascii $path
while ($true) {
$r = Test-Connection -ComputerName 8.8.8.8 -Count 1 -ErrorAction SilentlyContinue
$ms = if ($r) { $r.Latency } else { -1 }
"{0:o},8.8.8.8,{1}" -f (Get-Date), $ms | Add-Content -Encoding ascii $path
Start-Sleep -Seconds 1
}
Output:
(none — appends to CSV continuously)
Find the path MTU automatically
A binary search wrapper finds the largest payload that traverses the path without fragmentation in O(log n) probes.
@echo off
setlocal enabledelayedexpansion
set TARGET=%1
if "%TARGET%"=="" set TARGET=8.8.8.8
set LOW=0
set HIGH=1500
:loop
set /a MID=(LOW+HIGH)/2
ping -n 1 -w 1000 -l !MID! -f %TARGET% >NUL 2>&1
if !errorlevel! equ 0 (set LOW=!MID!) else (set HIGH=!MID!)
set /a DIFF=HIGH-LOW
if !DIFF! gtr 1 goto loop
set /a MTU=LOW+28
echo Path MTU to %TARGET%: !MTU! bytes
endlocal
Output:
Path MTU to 8.8.8.8: 1500 bytes
Detect intermittent loss over a long window
A scripted 1000-ping run with the loss percentage extracted gives a quantitative measure of an unstable link.
$ping = ping -n 1000 -w 500 8.8.8.8 | Select-String "Lost ="
$ping
Output:
Packets: Sent = 1000, Received = 988, Lost = 12 (1% loss),
A loss rate above 0.5% on Internet paths warrants escalation to the ISP; on a LAN, anything above 0% indicates cabling, NIC, or switch problems.
Verify ICMP is allowed inbound
A quick self-test: ping yourself by name from another host, or check the local firewall directly.
Get-NetFirewallRule -DisplayName "*Echo Request*" |
Select-Object DisplayName, Direction, Action, Enabled
Output:
DisplayName Direction Action Enabled
----------- --------- ------ -------
File and Printer Sharing (Echo Request - ICMPv4-In) Inbound Allow True
File and Printer Sharing (Echo Request - ICMPv6-In) Inbound Allow True
If Enabled is False, enable with Enable-NetFirewallRule -DisplayGroup "File and Printer Sharing".
Sweep a /24 to find live hosts
A quick host discovery sweep using parallel pings — faster than running them sequentially.
1..254 | ForEach-Object -Parallel {
$ip = "192.168.1.$_"
if (Test-Connection $ip -Count 1 -Quiet -TimeoutSeconds 1) {
"$ip UP"
}
} -ThrottleLimit 50
Output:
192.168.1.1 UP
192.168.1.10 UP
192.168.1.50 UP
192.168.1.100 UP
192.168.1.254 UP
-Parallel requires PowerShell 7+; in PowerShell 5.1 use a Workflow or Start-Job for the same effect.
See also
- ipconfig — view interfaces, gateways, and DNS
- tracert — locate where a path fails
- pathping — per-hop loss measurement
- arp — Layer 2 (ARP cache) view
- nslookup — resolve names to test before pinging
- netstat — see established TCP connections
- Linux
ping— cross-platform comparison (most flags are inverted:-c Ninstead of-n N, etc.)