mtr is the de facto standard for interactive traceroute but hasn't seen major feature development in years. trippy (Rust) is the main modern alternative but focuses on a different feature set.
Key advantages ttl already has:
- ECMP path enumeration with per-flow/per-packet classification (
--flows) - NAT detection (source port rewrite analysis)
- ICMP rate limit detection (distinguish rate limiting from real loss)
- Route flap and asymmetric routing detection
- TTL manipulation detection (transparent proxies, middleboxes)
- Path MTU discovery (
--pmtud) - IX detection via PeeringDB
- Animated session replay
- Dual-stack
--resolve-all(trace IPv4 and IPv6 simultaneously)
- ICMP Echo probing with TTL sweep
- IPv4 and IPv6 support with extension header handling
- Real-time TUI with ratatui (11 built-in themes)
- Hop statistics (loss, min/avg/max, stddev, jitter, percentiles)
- Reverse DNS resolution (parallel lookups)
- MPLS label detection (RFC 4884/4950 ICMP extensions)
- JSON, CSV, and report export formats
- Session replay from saved JSON
- Multiple simultaneous targets (
ttl 8.8.8.8 1.1.1.1) - NAT detection (source port rewrite analysis)
- Paris/Dublin traceroute (
--flowsfor ECMP path enumeration) - UDP probing (
-p udp) and TCP SYN probing (-p tcp) - Protocol auto-detection (
-p auto, default) - ASN lookup (Team Cymru DNS), GeoIP (MaxMind), IX detection (PeeringDB)
- Terminal injection protection (sanitize external data)
- Terminal state cleanup on error/panic
- Interface binding (
--interface,--recv-any) - Shell completions (
--completions bash/zsh/fish/powershell) - Settings modal (theme, display mode, PeeringDB API key)
- Target list overlay for multi-target mode
- Autosize columns (auto/compact/wide with
wkey cycling) - Linux binary compatibility (musl libc for broad distro support)
- Path MTU discovery (
--pmtud) with binary search - Packet size control (
--size) with DF flag - DSCP/ToS marking (
--dscp) for QoS policy testing - ICMP rate limit detection with TUI indicators
- Route flap detection (primary responder IP changes)
- Asymmetric routing detection (forward vs return path hops)
- TTL manipulation detection (transparent proxies, middleboxes)
- First-hop gateway detection via kernel APIs (netlink/sysctl)
- Rate limiting (
--rate) for slow links - Source IP selection (
--source-ip) - Update notifications (checks GitHub releases, install-method-aware)
- FreeBSD support (experimental, raw sockets)
- Animated replay (
--replay file --animate) with speed control - Probe event recording for replay accuracy
- TUI refresh rate increased to 60fps (#17)
- Jumbo frame support (
--sizeup to 9216,--jumbofor PMTUD) - Immediate sent counting (mtr parity — increments at probe send, not response)
- Dual-stack
--resolve-all(trace IPv4 and IPv6 simultaneously) - FreeBSD ICMP socket fix (RAW sockets, not DGRAM)
- Last RTT column in main table (mtr parity —
Loss% Snt Last Avg Min Max StdDev) - JAvg and JMax columns in Wide display mode
- Wider ASN column for full AS name visibility
- ECMP classification: per-flow vs per-packet detection with primary_ratio heuristic (#46)
- Paths column reflects actual responder count for per-packet ECMP (#46)
-
Eindicator for ECMP detected vs!for route flap (#46) - Effective flow capability:
--flows+ ICMP warns and collapses to single-flow (#46) - Receiver flow attribution hardening: unknown flows only match when unambiguous (#46)
- NetBSD platform support (experimental, raw sockets, IPv6 PMTUD only) (#47)
- NetBSD UDP source IP auto-detection (fixes EHOSTUNREACH on DGRAM sockets) (#47)
- Update checker: non-blocking
try_recv()polling in TUI (replaces blockingrecv_timeout(1s)) - Update checker: first-run immediate network check (
interval(Duration::ZERO)) - Interactive replay controls (seek, speed, progress bar) shipped in v0.19.0
- Pre-commit hooks (
.pre-commit-config.yamlforcargo fmt/clippy/test) - CI:
cargo clippy --all-targets -- -D warningson Linux, macOS, and FreeBSD - hickory-resolver 0.26 upgrade (closes RUSTSEC-2026-0118 and RUSTSEC-2026-0119)
- Trace diffing (
--diff before.json after.json): added/lost hops, path changes, latency shifts;--jsonfor machine-readable output - Streaming JSON output (
--stream-json): line-delimited probe events + per-target summary, composable with jq/grep - Daemon mode (
--daemon) with graceful SIGTERM shutdown (cleandocker stop) - Prometheus/OpenMetrics exporter (
--prometheus :9090) with/healthzfor orchestration - Official Dockerfile + multi-arch (amd64/arm64) GHCR images (
ghcr.io/lance0/ttl) - Interactive target selection:
ttlwith no args opens an empty session;oadds targets mid-session with runtime engine/receiver spawning - IX prefix lookup via binary radix trie (O(prefix_len) instead of O(n) linear scan)
- New
aarch64-unknown-linux-muslrelease artifact
- Opt out of the startup update check (#110):
--no-update-checkflag,DO_NOT_TRACK/TTL_NO_UPDATE_CHECKenv vars,no_update_checkconfig key, a TUI Settings toggle, and a--no-default-featuresbuild that compiles the check (andupdate-informer) out entirely
The macOS single-hop fix (#12) removes the stale-TTL race from the probe send paths, now complete across IPv4 and IPv6 on every platform. IPv4 is unified on IP_HDRINCL (TTL written into a hand-built IP header sent through one raw socket); IPv6 sends each probe from a fresh socket on the BSD-derived platforms (per_probe_send = macOS/FreeBSD/NetBSD). The rapid probe sweeps are race-free, so the interim timing delay is gone; the lone IPv6 PMTUD probe per round still uses the shared socket but is an isolated send. Validated on real Linux, macOS, and FreeBSD kernels in CI.
- Unify the IPv4 send path on
IP_HDRINCL. TTL in the IP header; per-OSip_len/ip_offbyte order handled (host order on macOS/NetBSD, network order on Linux/FreeBSD ≥11); transport (ICMP/UDP/TCP) checksums built in; CI runs a privileged real-kernel send test on Linux/macOS/FreeBSD. Also fixes IPv4 PMTUD on NetBSD (DF set in the header, not via the missingIP_DONTFRAG). - IPv6: deterministic per-packet hop limit on FreeBSD/NetBSD. Extended the per-probe-socket path (previously macOS-only) to FreeBSD/NetBSD via the new
per_probe_sendcfg (build.rs). Linux keeps one shared socket (no race there). - Dropped the 500µs
apply_rate_limitdelay. Redundant now that IPv4 usesIP_HDRINCLand IPv6 uses per-probe sockets on all BSD-derived platforms; only the explicit--ratedelay remains.
Why this matters: Per-packet load balancing (common on Arista, Juniper, Cisco) is undercounted by the current flow-primary model. Users see 8 responders in the detail view but "Paths: 1" in the main table. Related: #46
- Detect per-packet vs per-flow ECMP (primary_ratio heuristic per flow)
- Paths column reflects actual responder count for per-packet ECMP
- Separate indicators:
Efor ECMP detected vs!for route flap - Warn when
--flows > 1with effective ICMP probing (-p icmp, or-p autowhen auto-select resolves to ICMP) - Define
-p autowarning semantics for multi-target/mixed-family runs (warn if any target resolves to effective ICMP, avoid duplicate spam) - Track effective flow capability at runtime (requested
--flowsvs effective protocol) and use it for flap detection + NAT/Paths column visibility - Add CLI/TUI hint that flow-based ECMP detection is meaningful with UDP/TCP probes
- Keep Paths value + highlight + host indicator driven by one shared ECMP classification (avoid count/style drift)
- Handle out-of-range returned src ports as unknown flow (not forced flow 0) to avoid false per-flow attribution behind NAT/CGNAT
- Update indicator/UI budget for new
Emarker (host width autosize currently assumes" !~^") - Update user-facing indicator docs/help (
Evs!) in CLI help + docs pages - Add tests for per-packet ECMP classification,
-p autoICMP warning behavior, and out-of-range src-port flow attribution - #46 acceptance: per-packet ECMP no longer presents as misleading
Paths: 1when many responders are observed - #46 acceptance:
E(ECMP) and!(route flap) are no longer conflated in the same scenario - Paris strategy for UDP (
--strategy paris— fixed 5-tuple, checksum encodes sequence) (follow-on after #46 core fix) - Dublin strategy for UDP (
--strategy dublin— IP ID field encodes sequence) (follow-on after #46 core fix)
Prioritized by effort vs user impact. Quick wins first, then bigger lifts.
- Progress indicator in replay — show position in timeline during animated replay
- Interactive replay — step through events, jump to time, speed control
- Last metric semantics — documented as primary-responder-most-recent; TUI/CSV aligned
- IPv6 RAW payload fallback tests — unit tests for IPv6 Echo Reply and Time Exceeded parsing
- Main table layout tests — verify header/cell/width count parity across Auto/Compact/Wide × single-flow/multi-flow modes
- PCAP export — write probe/response packets to .pcap for Wireshark analysis
- IX lookup performance — radix trie for O(prefix_len) instead of O(n) linear scan
- Customizable columns — choose which stats to display in TUI
- Container image — pre-built multi-arch image on GHCR for CI/monitoring pipelines
- ICMP checksum flow variation — Paris traceroute for ICMP (vary checksum to create distinct flows). Neither ttl nor trippy implements this today. Requires platform-specific raw socket work (kernel checksum offloading on Linux, IP_HDRINCL). Note: Real-world value may be limited — Arista hardware flow-hashing platforms don't use ICMP checksum as entropy, so this approach won't create distinct flows on most switch hardware. TCP/UDP remain the reliable methods for multi-path detection. May still be useful on software load balancers.
- BGP & routing integration — looking glass queries, AS path display, RPKI/ROA validation
- Baseline comparison — save baseline, alert on latency/loss/path deviations
- Continuous logging mode — log path changes over hours/days
- Historical data storage — SQLite/file-based path history
- Custom keybindings — user-configurable key mappings
- World map visualization — ASCII/Unicode geographic path display
- Advanced protocol testing — TCP MSS clamping, ECN, fragmentation testing
- Multi-path validation — verify all ECMP paths are functional
- Library API stabilization (stable
lib.rsfor third-party integrations) - Comprehensive documentation for library consumers
- Semantic versioning commitment
- Integration tests for probe-receive-state pipeline
- Property-based/fuzz tests for packet parsing (correlate.rs)
- RAW payload fallback unit tests (IPv4)
- IPv6 RAW payload fallback unit tests
- Concurrent multi-target stress tests
- Basic ICMP traceroute (Npcap or Winsock raw sockets)
- TUI compatibility with Windows Terminal
- Pre-built binaries
Rationale: Massive Npcap effort. WSL2 works well. Revisit if demand warrants.
- Remote agent for measuring both directions
- One-way delay estimation (detect latency asymmetry)
Rationale: Requires deploying an agent on the remote side, which changes the tool's simplicity model.
- Bandwidth/capacity estimation (pathchar-style probing)
- SNMP integration (query router interface stats)
- Network topology learning (build graph from multiple traces)
Rationale: These push ttl toward being a full network management tool. Better served by purpose-built tools.
| Tool | Language | ECMP | MTU Discovery | Rate Limit Detection | TUI | Active Development |
|---|---|---|---|---|---|---|
| mtr | C | No | No | No | Yes | Maintenance |
| trippy | Rust | Yes (UDP) | No | No | Yes | Active |
| traceroute | C | No | Yes | No | No | Maintenance |
| tracepath | C | No | Yes | No | No | Maintenance |
| ttl | Rust | Yes (per-flow + per-packet) | Yes | Yes | Yes | Active |
ttl is a CLI traceroute tool. The following are explicitly out of scope:
- Web/mobile UI — this is a CLI tool, SSH into a box
- Shareable URLs / hosted trace service — JSON files are the sharing format
- Webhook/event streaming — use
--stream-json | curlinstead - Monitor mode with alerting — use Smokeping/Nagios for long-running monitoring
- Modular output plugins — Unix pipes are the plugin system
- Hop privacy mode (mask IPs for screenshots) — users can redact manually
- Multi-language TUI (i18n) — English-only is fine for CLI tools
- Full packet capture — use tcpdump/wireshark
- Bandwidth testing — use xfr or iperf
- Port scanning — use nmap
- Enterprise collaboration platform — not a SaaS product
If you need these features, combine ttl with purpose-built tools.
See KNOWN_ISSUES.md for documented edge cases and limitations.
- GitHub Actions CI (build, test, clippy, FreeBSD)
- Binary releases (Linux x86_64/aarch64, macOS x86_64/aarch64)
- Homebrew core formula (
brew install ttl) +lance0/tap/ttltap - Curl installer (
install.sh) - Dependabot (Cargo + GitHub Actions)
- AUR package (
ttl-bin, community-maintained) - Gentoo package (
net-analyzer/ttl, official repository) - Container image on GHCR (
ghcr.io/lance0/ttl, multi-arch, published on release) - Docker Hub mirror (optional — needs registry credentials; GHCR covers the use case)
See issues labeled good first issue for entry points. PRs welcome for any roadmap item.