ttl
Modern traceroute/mtr-style TUI with hop stats and optional ASN/geo enrichment.
Features
- Fast, low-overhead continuous path monitoring
- Multiple simultaneous targets: Trace to several destinations at once
- Useful hop-level stats (loss, min/avg/max, jitter, stddev, percentiles)
- RTT percentiles (p50, p95, p99) from sample history
- MPLS label detection from ICMP extensions
- ASN lookup via Team Cymru DNS (enabled by default)
- GeoIP lookup via MaxMind GeoLite2 database
- IX detection via PeeringDB: Identify Internet Exchange points in path
- ICMP, UDP, and TCP probing modes with auto-detection
- Paris/Dublin traceroute: Multi-flow probing for ECMP path enumeration
- NAT detection: Identify when NAT devices rewrite source ports
- ICMP rate limit detection: Identify misleading loss from router rate limiting
- Interface binding: Force probes through specific network interface
- Packet size control: Set probe size for MTU testing (
--size) - Path MTU discovery: Binary search to find maximum unfragmented size (
--pmtud) - DSCP/ToS marking: Set QoS marking for policy testing (
--dscp) - Great terminal UX built with ratatui
- Scriptable mode for CI and automation
- Reverse DNS resolution (parallel lookups)
- ECMP detection (multiple responders per TTL)
- Multiple export formats (JSON, CSV)
- Session replay from saved JSON files
- IPv4 and IPv6 support
Installation
From crates.io
From source
Permissions
Raw sockets require elevated privileges. Choose one:
# Option 1: Run with sudo
# Option 2: Add capability (Linux)
# Option 3: Enable unprivileged ICMP (Linux)
Platform Support
| Platform | Status | Notes |
|---|---|---|
| Linux | Full support | Raw sockets require CAP_NET_RAW or root |
| macOS | Full support | Requires root |
| Windows | Not supported | Would require WinPcap/Npcap |
Usage
Interactive TUI (default)
Multiple targets
# Trace to multiple destinations simultaneously
# Use Tab/n to switch between targets, Shift-Tab/N for previous
# Each target shows independent hop data
Report mode
JSON export
CSV export
Replay a saved session
Streaming output
Probing modes
# Auto-detect best protocol (default): ICMP → UDP → TCP
# Force specific protocol
# Custom port
# Fixed port (disable per-TTL variation)
Multi-flow ECMP detection (Paris/Dublin traceroute)
# Discover ECMP paths with 4 flows
# More flows for thorough path enumeration
# Custom source port base
Each flow uses a different source port, causing ECMP routers to route flows along different paths. The TUI shows a "Paths" column when --flows > 1, highlighted when multiple paths are detected.
Interface binding
# Bind all probes to specific interface
# Useful for multi-homed hosts or VPN split tunneling
# Allow asymmetric routing (don't bind receiver socket)
The --interface flag ensures probes egress through the specified network interface. This is useful on multi-homed systems where you need deterministic path selection.
The --recv-any flag (requires --interface) disables receiver socket binding. Use this when replies may arrive on a different interface than the one used for sending (asymmetric routing, VPN split-tunnel).
Packet size and DSCP marking
# Large packets for MTU testing (1400 bytes total)
# DSCP marking for QoS policy testing
# Combine both
DSCP values are set in the IP header TOS field. You can use tcpdump to verify: sudo tcpdump -v -n icmp | grep tos
Path MTU Discovery
# Discover the path MTU using binary search
PMTUD sends probes with the Don't Fragment (DF) flag set, binary searching between the minimum (68 bytes for IPv4, 1280 for IPv6) and maximum (1500 bytes) to find the largest packet size that passes without fragmentation. Results are shown in the TUI title bar.
Options
-c, --count <N> Number of probes (0 = infinite, default)
-i, --interval <S> Probe interval in seconds (default: 1.0)
-m, --max-ttl <N> Maximum TTL (default: 30)
-p, --protocol <P> Probe protocol: auto (default), icmp, udp, tcp
--port <N> Base port for UDP/TCP probes
--fixed-port Use fixed port (disable per-TTL variation)
--flows <N> Number of flows for ECMP detection (1-16, default: 1)
--src-port <N> Base source port for multi-flow (default: 50000)
--timeout <S> Probe timeout in seconds (default: 3)
--size <N> Packet size in bytes (36-1500 for IPv4, 56+ for IPv6)
--dscp <N> DSCP value for QoS testing (0-63)
--rate <N> Max probes per second (0 = unlimited)
--pmtud Enable Path MTU Discovery (binary search for max unfragmented size)
--source-ip <IP> Force specific source IP address
--interface <NAME> Bind probes to specific network interface
--recv-any Don't bind receiver to interface (asymmetric routing)
-4, --ipv4 Force IPv4
-6, --ipv6 Force IPv6
--no-dns Skip reverse DNS lookups
--no-asn Skip ASN enrichment
--no-geo Skip geolocation
--no-ix Skip IX detection (PeeringDB)
--geoip-db <PATH> Path to MaxMind GeoLite2 database
--no-tui Streaming output mode
--report Batch report mode (requires -c)
--json JSON output (requires -c)
--csv CSV output (requires -c)
--replay <FILE> Replay a saved JSON session
--theme <NAME> Color theme (see Themes section)
Keybindings
| Key | Action |
|---|---|
q |
Quit |
p |
Pause/Resume |
r |
Reset stats |
t |
Cycle theme |
e |
Export to JSON |
? / h |
Help |
Up / k |
Move selection up |
Down / j |
Move selection down |
Enter |
Expand selected hop |
Esc |
Close popup / Deselect |
Themes
11 built-in themes are available. Set via --theme flag or cycle with t key in the TUI.
| Theme | Description |
|---|---|
default |
Classic cyan borders (original ttl look) |
kawaii |
Cute pastel colors |
cyber |
Neon cyan/magenta on dark |
dracula |
Popular dark theme |
monochrome |
Grayscale only |
matrix |
Green on black hacker style |
nord |
Arctic, north-bluish colors |
gruvbox |
Retro groove warm colors |
catppuccin |
Soothing pastel colors |
tokyo_night |
Tokyo city lights inspired |
solarized |
Precision colors for readability |
# Start with a specific theme
# Press 't' during runtime to cycle themes
# Your selection is saved to ~/.config/ttl/config.toml
Environment Variables
| Variable | Description |
|---|---|
PEERINGDB_API_KEY |
PeeringDB API key for higher rate limits on IX detection. Get one at peeringdb.com. Without a key, anonymous API access is rate-limited. |
Troubleshooting
Permission errors
Error: Insufficient permissions for raw sockets
Raw ICMP sockets require elevated privileges. See the Permissions section above.
High packet loss
If you see high loss (>10%) to a destination that should be reachable:
- Network congestion - Some routers deprioritize ICMP traffic
- Rate limiting - Target may rate-limit ICMP responses
- Firewall - Intermediate firewalls may drop ICMP
- ECMP paths - Multiple paths with different characteristics
Try increasing the probe interval: ttl target -i 2.0
All hops showing * * *
This usually means:
- Firewall blocking - Your outbound ICMP is blocked
- VPN interference - Some VPNs don't pass ICMP correctly
- Target unreachable - Verify the IP/hostname is correct
IPv6 not working
- Verify IPv6 connectivity:
ping6 2001:4860:4860::8888 - Force IPv6:
ttl -6 google.com - Check if your ISP supports IPv6
DNS resolution slow
Reverse DNS lookups can be slow. Disable with --no-dns for faster startup.
Statistics Explained
Jitter
Jitter measures RTT variance - the absolute difference between consecutive round-trip times (|RTT_n - RTT_n-1|). This is different from inter-packet arrival jitter used in VoIP/streaming contexts.
Three jitter metrics are tracked:
| Metric | Description |
|---|---|
| Jitter (smoothed) | RFC 3550-style EWMA with 1/16 smoothing factor. Tracks trends while filtering noise. |
| Avg Jitter | Running mean of all jitter observations. Shows overall session variance. |
| Max Jitter | Largest single RTT change. Captures worst-case latency spike. |
Interpretation: High jitter indicates path instability from congestion, route changes, bufferbloat, or load balancing. Stable paths typically show jitter below 5-10% of average RTT.
Other Statistics
| Metric | Description |
|---|---|
| Loss % | Percentage of probes that timed out without response |
| Min/Avg/Max | RTT range across all samples |
| StdDev | Standard deviation of RTT (Welford's algorithm) |
| p50/p95/p99 | RTT percentiles from last 256 samples |
Tech Stack
- Language: Rust
- TUI: ratatui + crossterm
- Async: tokio
- Sockets: socket2 + pnet
- DNS: hickory-resolver
Comparison with Similar Tools
| Feature | ttl | Trippy | MTR | NextTrace |
|---|---|---|---|---|
| Protocols | ||||
| ICMP | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| UDP | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| TCP | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Statistics | ||||
| Loss % | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Min/Avg/Max RTT | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Jitter | :white_check_mark: | :white_check_mark: | :x: | :x: |
| Std deviation | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| Enrichment | ||||
| Reverse DNS | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| ASN lookup | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: |
| GeoIP | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: |
| MPLS labels | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| IX detection | :white_check_mark: | :x: | :x: | :x: |
| ECMP | ||||
| Multi-path detection | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Paris traceroute | :white_check_mark: | :white_check_mark: | :x: | :x: |
| TUI | ||||
| Interactive | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| Themes | :white_check_mark: | :white_check_mark: | :x: | :x: |
| Theme persistence | :white_check_mark: | :white_check_mark: | :x: | :x: |
| Sparklines/charts | :white_check_mark: | :white_check_mark: | :x: | :x: |
| World map | :x: | :white_check_mark: | :x: | :white_check_mark: |
| Export | ||||
| JSON | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| CSV | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| Session replay | :white_check_mark: | :x: | :x: | :x: |
:white_check_mark: = supported | :construction: = planned | :x: = not supported
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.