Fast, modern traceroute with real-time TUI, per-hop stats, ASN/geo lookup, ECMP detection, and MPLS label parsing. A better mtr.
Rust
1,474
310 commits
updated Oct 8, 2026
Network diagnostic tool that goes beyond traceroute: MTU discovery, NAT detection, route flap alerts, IX identification, and more.
# Basic usage
ttl 8.8.8.8 # Linux (after setcap)
sudo ttl 8.8.8.8 # macOS/BSD (always needs sudo)
# Common options
ttl -p udp google.com # UDP probes
ttl --flows 8 cloudflare.com # ECMP path discovery
ttl --pmtud 1.1.1.1 # Path MTU discovery
ttl 8.8.8.8 1.1.1.1 9.9.9.9 # Multiple targets
ttl --resolve-all google.com # Trace all resolved IPs
See Installation below for setup instructions.
--no-update-check, DO_NOT_TRACK, config, or a --no-default-features build)/metrics and /healthzSee docs/FEATURES.md for detailed documentation, including optional setup for GeoIP and IX detection.
Requires Rust:
# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Install ttl
cargo install ttl
brew install ttl
Available directly from Homebrew core. (The lance0/tap/ttl tap also still works and may ship new releases slightly sooner.)
apk add ttl --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing
Currently in the edge/testing repository (community-maintained).
yay -S ttl-bin
emerge net-analyzer/ttl
pkgin install ttl
Or from source: cd /usr/pkgsrc/net/ttl && make install
# Imperative install
nix-env -iA nixpkgs.ttl
# NixOS configuration
environment.systemPackages = [ pkgs.ttl ];
# Temporary shell
nix-shell -p ttl
Available in nixpkgs unstable (community-maintained).
Download from GitHub Releases:
| Platform | Target |
|---|---|
| Linux x86_64 | ttl-x86_64-unknown-linux-musl.tar.gz |
| Linux ARM64 | ttl-aarch64-unknown-linux-gnu.tar.gz |
| macOS Apple Silicon | ttl-aarch64-apple-darwin.tar.gz |
| macOS Intel | ttl-x86_64-apple-darwin.tar.gz |
# Download, verify, and install (Linux x86_64 example)
curl -LO https://github.com/lance0/ttl/releases/latest/download/ttl-x86_64-unknown-linux-musl.tar.gz
curl -LO https://github.com/lance0/ttl/releases/latest/download/SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing # macOS: shasum -a 256 -c
tar xzf ttl-*.tar.gz && sudo mv ttl /usr/local/bin/
Multi-arch images (amd64/arm64) are published to GHCR on each release:
docker pull ghcr.io/lance0/ttl:latest
docker run --rm -it ghcr.io/lance0/ttl 8.8.8.8
# Headless monitoring with Prometheus metrics
docker run -d -p 9090:9090 ghcr.io/lance0/ttl --daemon --prometheus :9090 8.8.8.8
Docker grants the required NET_RAW capability by default; stricter runtimes may need --cap-add NET_RAW.
git clone https://github.com/lance0/ttl
cd ttl && cargo build --release
sudo cp target/release/ttl /usr/local/bin/
Note: Piping scripts from the internet to sh is convenient but bypasses your ability to review the code first. Consider using one of the methods above, or review the script before running.
curl -fsSL https://raw.githubusercontent.com/lance0/ttl/master/install.sh | sh
Raw sockets require elevated privileges. The easiest approach is to add the capability once:
# Add capability (works for any install location)
sudo setcap cap_net_raw+ep $(which ttl)
# Then run without sudo:
ttl 8.8.8.8
# Bash
ttl --completions bash > ~/.local/share/bash-completion/completions/ttl
# Zsh (add ~/.zfunc to fpath in .zshrc first)
ttl --completions zsh > ~/.zfunc/_ttl
# Fish
ttl --completions fish > ~/.config/fish/completions/ttl.fish
# PowerShell (add to $PROFILE)
ttl --completions powershell >> $PROFILE
ttl google.com
ttl 8.8.8.8 1.1.1.1 # Multiple targets (Tab to switch)
ttl 1.1.1.1 -c 100 --report # Text report
ttl 1.1.1.1 -c 100 --json # JSON export
ttl 1.1.1.1 -c 100 --csv # CSV export
ttl 1.1.1.1 --stream-json # Stream events as line-delimited JSON
ttl --diff before.json after.json # Compare two saved sessions
ttl --daemon --prometheus :9090 1.1.1.1 # Headless + Prometheus metrics
ttl --replay results.json # Replay saved session
ttl --replay results.json --animate # Animated replay
ttl -p tcp --port 443 host # TCP probes to HTTPS
ttl --flows 4 host # ECMP path enumeration
ttl --interface eth0 host # Bind to interface
ttl --size 1400 host # Large packets for MTU testing
ttl --dscp 46 host # QoS marking (EF)
ttl --wide host # Wide mode for wider terminals
ttl --no-update-check host # Skip the startup release check (see also DO_NOT_TRACK)
See docs/FEATURES.md for full CLI reference.
VPN tunnels often have lower MTU than expected. Large packets get silently dropped, causing mysterious connection hangs.
sudo ttl --pmtud vpn-gateway.example.com
TTL binary-searches to find the maximum packet size that works. The [MTU: 1400] indicator shows exactly where fragmentation occurs.
Running multi-flow traceroute but getting inconsistent results? NAT devices may be rewriting your source ports.
sudo ttl --flows 4 target.com
TTL detects when returned source ports don't match what was sent. The [NAT] indicator warns you, and hop details show which device is doing the rewriting.
See exactly where your traffic peers with other networks:
sudo ttl cloudflare.com
TTL queries PeeringDB to identify IX points. The hop detail view shows IX name, city, and country. Works out of the box; optionally configure an API key via settings (s key) or PEERINGDB_API_KEY env var for higher rate limits. See docs/FEATURES.md for setup details.
Unstable BGP or failover issues cause intermittent problems that are hard to catch:
sudo ttl -i 0.5 production-server.com
TTL tracks when the responding IP at a hop changes. The ! indicator flags route flaps, and hop details show change history. ECMP load balancing shows E instead, so you can distinguish real instability from expected multi-path behavior.
Some networks intercept traffic with transparent proxies that manipulate TTL values:
sudo ttl -p tcp --port 80 website.com
The [TTL!] indicator appears when TTL manipulation is detected.
That 30% packet loss at hop 5 might be fake - routers often rate-limit ICMP responses:
sudo ttl target.com
The [RL?] indicator and 50%RL in the loss column tell you it's rate limiting, not actual packet drops.
sudo ttl 8.8.8.8 1.1.1.1 9.9.9.9
Trace multiple destinations at once. Press Tab to switch between them, or l to see a list of all targets.
sudo ttl --resolve-all google.com
When a hostname resolves to multiple IPs (round-robin DNS, CDN load balancing), trace all of them to compare paths. Press l to see all resolved targets with their stats.
| Key | Action |
|---|---|
q / Ctrl+C | Quit |
p / Space | Pause/Resume |
r | Reset stats |
t | Cycle theme |
w | Cycle display mode |
s | Settings |
e | Export JSON |
? | Help |
u | Dismiss update banner |
o | Add target |
Tab | Next target |
l | Target list |
Enter | Expand hop |
← / → | Replay: seek ±0.5s |
[ / ] | Replay: seek ±5s |
+ / - | Replay: speed ±0.5x |
Home / End | Replay: jump to start/end |
Replay controls are active in --animate replay mode only. See docs/FEATURES.md for the full table.
11 built-in themes: default, kawaii, cyber, dracula, monochrome, matrix, nord, gruvbox, catppuccin, tokyo_night, solarized
ttl 1.1.1.1 --theme dracula # Start with theme
# Press 't' to cycle themes (saved to ~/.config/ttl/config.toml)
| Platform | Status |
|---|---|
| Linux | Full support |
| macOS (Tahoe 26+) | Full support |
| macOS (Sequoia 15) | Build from source* |
| FreeBSD | Experimental** |
| NetBSD | Experimental** |
| Windows (WSL2) | Full support |
| Windows (native) | Not supported |
*Pre-built binaries are built on macos-latest (Tahoe). Older macOS versions may have display issues - use cargo install ttl to compile from source.
**FreeBSD/NetBSD support is experimental. Requires sudo. Interface binding (-i) is not supported. Please report issues at https://github.com/lance0/ttl/issues
wsl --install # Install WSL if needed, then restart
wsl # Open Ubuntu
Then in Ubuntu:
# Option 1: Install via cargo (recommended)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
cargo install ttl
sudo ~/.cargo/bin/ttl 8.8.8.8
# Option 2: Pre-built binary via install script
curl -fsSL https://raw.githubusercontent.com/lance0/ttl/master/install.sh | sh
sudo ttl 8.8.8.8
r to reset, or use Terminal.app.CAP_NET_RAW capability or root (see Permissions)sudo ttl target) - RAW sockets are needed to receive ICMP Time Exceeded messages from intermediate routers-p udp or -p tcp[NAT] indicator warns when this is detectedsudo uses a restricted PATH. Use the full path or copy to a sudo-accessible location:
# Option 1: Use full path
sudo ~/.cargo/bin/ttl 8.8.8.8
# Option 2: Copy to /usr/local/bin (one-time)
sudo cp ~/.cargo/bin/ttl /usr/local/bin/
# Option 3: Symlink (updates automatically with cargo install)
sudo ln -sf ~/.cargo/bin/ttl /usr/local/bin/ttl
Raw ICMP sockets require CAP_NET_RAW or root. See Permissions.
Try increasing probe interval: ttl target -i 2.0
Some routers rate-limit ICMP - look for the [RL?] indicator in the TUI.
* * *Check firewall rules, VPN configuration, or try a different protocol: ttl -p udp target
As of v0.12.1, the config directory on macOS changed from ~/Library/Preferences/ttl/ to ~/Library/Application Support/ttl/ to align with Apple guidelines. If you have an existing config, move it:
mv ~/Library/Preferences/ttl ~/Library/Application\ Support/ttl
Licensed under either of:
at your option.
(top 24 of 44)
5,482 followers · starred Jun 2026
1,271 followers · starred Jan 2026
115 followers · starred Jan 2026
5,444 followers · starred Jan 2026
Fast, modern traceroute with real-time TUI, per-hop stats, ASN/geo lookup, ECMP detection, and MPLS label parsing. A better mtr.
Rust
1,474
310 commits
updated Oct 8, 2026
Network diagnostic tool that goes beyond traceroute: MTU discovery, NAT detection, route flap alerts, IX identification, and more.
# Basic usage
ttl 8.8.8.8 # Linux (after setcap)
sudo ttl 8.8.8.8 # macOS/BSD (always needs sudo)
# Common options
ttl -p udp google.com # UDP probes
ttl --flows 8 cloudflare.com # ECMP path discovery
ttl --pmtud 1.1.1.1 # Path MTU discovery
ttl 8.8.8.8 1.1.1.1 9.9.9.9 # Multiple targets
ttl --resolve-all google.com # Trace all resolved IPs
See Installation below for setup instructions.
--no-update-check, DO_NOT_TRACK, config, or a --no-default-features build)/metrics and /healthzSee docs/FEATURES.md for detailed documentation, including optional setup for GeoIP and IX detection.
Requires Rust:
# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Install ttl
cargo install ttl
brew install ttl
Available directly from Homebrew core. (The lance0/tap/ttl tap also still works and may ship new releases slightly sooner.)
apk add ttl --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing
Currently in the edge/testing repository (community-maintained).
yay -S ttl-bin
emerge net-analyzer/ttl
pkgin install ttl
Or from source: cd /usr/pkgsrc/net/ttl && make install
# Imperative install
nix-env -iA nixpkgs.ttl
# NixOS configuration
environment.systemPackages = [ pkgs.ttl ];
# Temporary shell
nix-shell -p ttl
Available in nixpkgs unstable (community-maintained).
Download from GitHub Releases:
| Platform | Target |
|---|---|
| Linux x86_64 | ttl-x86_64-unknown-linux-musl.tar.gz |
| Linux ARM64 | ttl-aarch64-unknown-linux-gnu.tar.gz |
| macOS Apple Silicon | ttl-aarch64-apple-darwin.tar.gz |
| macOS Intel | ttl-x86_64-apple-darwin.tar.gz |
# Download, verify, and install (Linux x86_64 example)
curl -LO https://github.com/lance0/ttl/releases/latest/download/ttl-x86_64-unknown-linux-musl.tar.gz
curl -LO https://github.com/lance0/ttl/releases/latest/download/SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing # macOS: shasum -a 256 -c
tar xzf ttl-*.tar.gz && sudo mv ttl /usr/local/bin/
Multi-arch images (amd64/arm64) are published to GHCR on each release:
docker pull ghcr.io/lance0/ttl:latest
docker run --rm -it ghcr.io/lance0/ttl 8.8.8.8
# Headless monitoring with Prometheus metrics
docker run -d -p 9090:9090 ghcr.io/lance0/ttl --daemon --prometheus :9090 8.8.8.8
Docker grants the required NET_RAW capability by default; stricter runtimes may need --cap-add NET_RAW.
git clone https://github.com/lance0/ttl
cd ttl && cargo build --release
sudo cp target/release/ttl /usr/local/bin/
Note: Piping scripts from the internet to sh is convenient but bypasses your ability to review the code first. Consider using one of the methods above, or review the script before running.
curl -fsSL https://raw.githubusercontent.com/lance0/ttl/master/install.sh | sh
Raw sockets require elevated privileges. The easiest approach is to add the capability once:
# Add capability (works for any install location)
sudo setcap cap_net_raw+ep $(which ttl)
# Then run without sudo:
ttl 8.8.8.8
# Bash
ttl --completions bash > ~/.local/share/bash-completion/completions/ttl
# Zsh (add ~/.zfunc to fpath in .zshrc first)
ttl --completions zsh > ~/.zfunc/_ttl
# Fish
ttl --completions fish > ~/.config/fish/completions/ttl.fish
# PowerShell (add to $PROFILE)
ttl --completions powershell >> $PROFILE
ttl google.com
ttl 8.8.8.8 1.1.1.1 # Multiple targets (Tab to switch)
ttl 1.1.1.1 -c 100 --report # Text report
ttl 1.1.1.1 -c 100 --json # JSON export
ttl 1.1.1.1 -c 100 --csv # CSV export
ttl 1.1.1.1 --stream-json # Stream events as line-delimited JSON
ttl --diff before.json after.json # Compare two saved sessions
ttl --daemon --prometheus :9090 1.1.1.1 # Headless + Prometheus metrics
ttl --replay results.json # Replay saved session
ttl --replay results.json --animate # Animated replay
ttl -p tcp --port 443 host # TCP probes to HTTPS
ttl --flows 4 host # ECMP path enumeration
ttl --interface eth0 host # Bind to interface
ttl --size 1400 host # Large packets for MTU testing
ttl --dscp 46 host # QoS marking (EF)
ttl --wide host # Wide mode for wider terminals
ttl --no-update-check host # Skip the startup release check (see also DO_NOT_TRACK)
See docs/FEATURES.md for full CLI reference.
VPN tunnels often have lower MTU than expected. Large packets get silently dropped, causing mysterious connection hangs.
sudo ttl --pmtud vpn-gateway.example.com
TTL binary-searches to find the maximum packet size that works. The [MTU: 1400] indicator shows exactly where fragmentation occurs.
Running multi-flow traceroute but getting inconsistent results? NAT devices may be rewriting your source ports.
sudo ttl --flows 4 target.com
TTL detects when returned source ports don't match what was sent. The [NAT] indicator warns you, and hop details show which device is doing the rewriting.
See exactly where your traffic peers with other networks:
sudo ttl cloudflare.com
TTL queries PeeringDB to identify IX points. The hop detail view shows IX name, city, and country. Works out of the box; optionally configure an API key via settings (s key) or PEERINGDB_API_KEY env var for higher rate limits. See docs/FEATURES.md for setup details.
Unstable BGP or failover issues cause intermittent problems that are hard to catch:
sudo ttl -i 0.5 production-server.com
TTL tracks when the responding IP at a hop changes. The ! indicator flags route flaps, and hop details show change history. ECMP load balancing shows E instead, so you can distinguish real instability from expected multi-path behavior.
Some networks intercept traffic with transparent proxies that manipulate TTL values:
sudo ttl -p tcp --port 80 website.com
The [TTL!] indicator appears when TTL manipulation is detected.
That 30% packet loss at hop 5 might be fake - routers often rate-limit ICMP responses:
sudo ttl target.com
The [RL?] indicator and 50%RL in the loss column tell you it's rate limiting, not actual packet drops.
sudo ttl 8.8.8.8 1.1.1.1 9.9.9.9
Trace multiple destinations at once. Press Tab to switch between them, or l to see a list of all targets.
sudo ttl --resolve-all google.com
When a hostname resolves to multiple IPs (round-robin DNS, CDN load balancing), trace all of them to compare paths. Press l to see all resolved targets with their stats.
| Key | Action |
|---|---|
q / Ctrl+C | Quit |
p / Space | Pause/Resume |
r | Reset stats |
t | Cycle theme |
w | Cycle display mode |
s | Settings |
e | Export JSON |
? | Help |
u | Dismiss update banner |
o | Add target |
Tab | Next target |
l | Target list |
Enter | Expand hop |
← / → | Replay: seek ±0.5s |
[ / ] | Replay: seek ±5s |
+ / - | Replay: speed ±0.5x |
Home / End | Replay: jump to start/end |
Replay controls are active in --animate replay mode only. See docs/FEATURES.md for the full table.
11 built-in themes: default, kawaii, cyber, dracula, monochrome, matrix, nord, gruvbox, catppuccin, tokyo_night, solarized
ttl 1.1.1.1 --theme dracula # Start with theme
# Press 't' to cycle themes (saved to ~/.config/ttl/config.toml)
| Platform | Status |
|---|---|
| Linux | Full support |
| macOS (Tahoe 26+) | Full support |
| macOS (Sequoia 15) | Build from source* |
| FreeBSD | Experimental** |
| NetBSD | Experimental** |
| Windows (WSL2) | Full support |
| Windows (native) | Not supported |
*Pre-built binaries are built on macos-latest (Tahoe). Older macOS versions may have display issues - use cargo install ttl to compile from source.
**FreeBSD/NetBSD support is experimental. Requires sudo. Interface binding (-i) is not supported. Please report issues at https://github.com/lance0/ttl/issues
wsl --install # Install WSL if needed, then restart
wsl # Open Ubuntu
Then in Ubuntu:
# Option 1: Install via cargo (recommended)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
cargo install ttl
sudo ~/.cargo/bin/ttl 8.8.8.8
# Option 2: Pre-built binary via install script
curl -fsSL https://raw.githubusercontent.com/lance0/ttl/master/install.sh | sh
sudo ttl 8.8.8.8
r to reset, or use Terminal.app.CAP_NET_RAW capability or root (see Permissions)sudo ttl target) - RAW sockets are needed to receive ICMP Time Exceeded messages from intermediate routers-p udp or -p tcp[NAT] indicator warns when this is detectedsudo uses a restricted PATH. Use the full path or copy to a sudo-accessible location:
# Option 1: Use full path
sudo ~/.cargo/bin/ttl 8.8.8.8
# Option 2: Copy to /usr/local/bin (one-time)
sudo cp ~/.cargo/bin/ttl /usr/local/bin/
# Option 3: Symlink (updates automatically with cargo install)
sudo ln -sf ~/.cargo/bin/ttl /usr/local/bin/ttl
Raw ICMP sockets require CAP_NET_RAW or root. See Permissions.
Try increasing probe interval: ttl target -i 2.0
Some routers rate-limit ICMP - look for the [RL?] indicator in the TUI.
* * *Check firewall rules, VPN configuration, or try a different protocol: ttl -p udp target
As of v0.12.1, the config directory on macOS changed from ~/Library/Preferences/ttl/ to ~/Library/Application Support/ttl/ to align with Apple guidelines. If you have an existing config, move it:
mv ~/Library/Preferences/ttl ~/Library/Application\ Support/ttl
Licensed under either of:
at your option.
(top 24 of 44)
5,482 followers · starred Jun 2026
1,271 followers · starred Jan 2026
115 followers · starred Jan 2026
5,444 followers · starred Jan 2026