traceroute and mtr: Tracing Network Paths and Finding the Slow Hop
What You'll Learn
- How to use
tracerouteto map the path (which routers your packets pass through) - How to use
mtrto continuously measure per-hop loss and latency and isolate the problem segment - How to read
* * *and intermediate-hop loss correctly instead of misjudging them
Quick Summary
- See the path and destination once →
traceroute - See where loss or latency happens →
mtr - Ignore loss at intermediate hops only (ICMP rate limiting). Loss that reaches the final hop is the real problem
Assumptions
- OS: Ubuntu / general Linux
tracerouteandmtrare separate packages. Install withsudo apt install traceroute mtr-tiny
What is traceroute actually doing?
Conclusion: It sends packets with TTL increasing from 1 and rebuilds the path one hop at a time from the ICMP Time Exceeded messages each router returns.
Every IP packet carries a TTL (Time To Live) counter: how many more routers it may cross. Each router decrements TTL by 1, and a packet whose TTL hits 0 is discarded — the router sends an ICMP Time Exceeded message back to the sender.
traceroute exploits this.
- Send a packet with TTL=1 → the first router drops it and replies → hop 1 revealed
- Send TTL=2 → the second router replies → hop 2 revealed
- Keep increasing TTL until the destination is reached
It sends 3 probes per hop by default, so each line shows three round-trip times (RTT).
$ traceroute example.com
traceroute to example.com (93.184.216.34), 30 hops max, 60 byte packets 1 _gateway (192.168.1.1) 0.512 ms 0.498 ms 0.471 ms 2 10.0.0.1 (10.0.0.1) 4.231 ms 4.118 ms 4.090 ms 3 * * * 4 93.184.216.34 (93.184.216.34) 12.043 ms 11.998 ms 12.110 ms
Does * * * mean something is broken?
Conclusion: Usually not. A router simply chose not to reply; if hops beyond it still respond, the path is fine.
* * * means "no reply to any of the 3 probes." The common causes are:
- The router suppresses TTL-exceeded replies (firewall / policy)
- It blocks UDP probes (Linux traceroute defaults to UDP)
- It hit a response rate limit
Rule of thumb: if hops after the * * * respond, the path is working. Only suspect reachability when * continues all the way to the final hop (the destination).
If you suspect UDP is being blocked, change the probe method.
# ICMP Echo (same packet type as ping) $ sudo traceroute -I example.com # TCP SYN to port 443 (closest to real HTTPS traffic) $ sudo traceroute -T -p 443 example.com
-I (ICMP) and -T (TCP) use raw sockets and need root (sudo). The default UDP mode runs as a regular user.
Which traceroute options matter?
Conclusion: Start with
-n(skip DNS for speed),-T -p(probe over TCP), and-m(max hops).
| Option | Meaning |
|---|---|
-n |
Do not resolve IPs to names (faster) |
-I |
Probe with ICMP Echo |
-T |
Probe with TCP SYN (use -p for the port) |
-p PORT |
Destination port (with -T, e.g. 443) |
-m N |
Maximum hops (default 30) |
-q N |
Probes per hop (default 3) |
-w SEC |
Reply wait timeout in seconds |
# Numeric, max 20 hops, one probe per hop — quick scan $ traceroute -n -m 20 -q 1 example.com
If reverse DNS lookups make it feel slow, add -n first.
How is mtr different from traceroute?
Conclusion: traceroute is a one-shot snapshot of the path; mtr keeps pinging every hop on the path and updates loss and latency stats in real time.
Network trouble flickers in and out. A single traceroute can't catch the intermittent case. mtr merges traceroute (path discovery) with ping (continuous measurement) and monitors every hop continuously.
$ mtr example.com
Packets Pings Host Loss% Snt Last Avg Best Wrst StDev 1. _gateway 0.0% 20 0.5 0.6 0.4 1.2 0.2 2. 10.0.0.1 0.0% 20 4.2 4.3 4.0 6.1 0.5 3. 203.0.113.1 10.0% 20 18.0 19.4 17.2 41.0 5.1 4. 93.184.216.34 0.0% 20 12.0 12.1 11.9 12.4 0.1
The columns mean:
- Loss%: share of probes with no reply at that hop
- Snt: probes sent
- Last / Avg / Best / Wrst: latest / average / minimum / maximum RTT (ms)
- StDev: RTT variation (higher = less stable)
How do you read loss in mtr?
Conclusion: Loss at an intermediate hop that drops back to 0% at the final hop is fake loss from ICMP rate limiting. Only loss that persists to the final hop is real.
This is mtr's biggest trap and its most important lesson. In the output above, hop 3 shows 10.0% loss, yet the final hop 4 is back to 0.0%.
Routers often deprioritize or throttle the TTL-exceeded replies addressed to themselves. So hop 3's 10.0% just means "hop 3 dropped some of its own replies" — the traffic itself passes straight through.
Decision rule
- Intermediate-hop loss → ignore it unless it propagates to the final hop (ICMP rate-limit false positive)
- Final-hop (destination) loss → real packet loss. The segment where the loss first rises and continues is the culprit
In short, watch where loss starts and stays through to the end. Discard loss that disappears later.
How do you pinpoint the slow segment?
Conclusion: If Avg jumps at one hop and stays high for the rest, that segment is the latency source. A spike that drops back is just delayed reply processing, with no real impact.
Latency reads the same way as loss.
- Avg jumps at a hop and stays high for every later hop → that segment (previous hop → this hop) is the real latency source
- Only Wrst spikes at one hop while Avg stays low → that router merely delayed its reply; not real path latency
# Report mode: send 10 cycles, then print final results (for logs / tickets) $ mtr -rwzbc 10 example.com
Option meanings:
-r/--report: print aggregated results once instead of the interactive screen-w: wide output (do not truncate hostnames)-z: show each hop's AS number (which provider's network it is)-b: show both hostname and IP-c N: number of cycles to send (default 10)-n: skip name resolution (faster)
When sending a report to your ISP or infra team, attach a report with more cycles, e.g. mtr -rwzbc 100 host. More samples make the loss figures more trustworthy and speed up the conversation.
traceroute vs mtr: which to use
Conclusion: Use traceroute to check the path once, and mtr to continuously isolate where loss or latency occurs. Attach mtr's report output when you report an issue.
| Situation | Use |
|---|---|
| See the path to a host once | traceroute -n |
UDP blocked, * * * keeps appearing |
traceroute -T -p 443 |
| Continuously measure loss / latency | mtr host |
| Share results as an issue report | mtr -rwzbc 100 host |
Common misreadings
- Treating an intermediate
* * *as a fault - Believing intermediate-hop loss that returns to 0% at the final hop
- Concluding "all good" from a single traceroute run