Inspect and Safely Clear Linux TCP Metrics
A stale cached round-trip time can make a fixed network problem look like it is still broken, and ip tcp_metrics is how you check and clear it. This inspects the kernel's cached TCP information, removes one destination entry, and prepares a narrowly scoped flush when a reset is justified. Allow about ten minutes for a read-only inspection, or longer if you need to identify which destination is safe to remove. The examples use iproute2 6.1.0 on this machine; other releases can change output details, so verify the installed command before scripting against it.
The route
Jump straight to the step you need, or tick off Done means at the end.
1. Check the installed command
Start by confirming which ip binary is in use and which iproute2 release it reports. This step is ordinary, unprivileged inspection:
$ command -v ip
/usr/sbin/ip
$ ip -V
ip utility, iproute2-6.1.0, libbpf 1.3.0
The subcommand is written as ip tcp_metrics. Some builds also accept the compact spelling shown by the help output, but use the longer spelling in notes and scripts because it is easier to recognise later:
$ ip tcp_metrics help
Usage: ip tcp_metrics/tcpmetrics { COMMAND | help }
ip tcp_metrics { show | flush } SELECTOR
ip tcp_metrics delete [ address ] ADDRESS
SELECTOR := [ [ address ] PREFIX ]
Checkpoint
Stop if ip -V reports an unexpected installation. A different binary may have different output or permissions.
2. List the cached entries
Run a read-only query before changing anything. With no selector, show lists all entries:
$ ip tcp_metrics show
127.0.0.1 age 204705.985sec cwnd 10 rtt 32us rttvar 19us source 127.0.0.53
Your list is host-specific and may be empty. The cache is keyed by destination address and can hold IPv4 and IPv6 information shared by TCP sockets. Fields can include the entry age, congestion window, round-trip time, round-trip variation, slow-start threshold, reordering value, Fast Open data, and TIME-WAIT timestamp information. Do not treat one field as a live connection statistic: these are saved metrics, not a dump of every current socket.
To reduce the output to a destination or network prefix, pass the prefix directly. The address word is optional:
$ ip tcp_metrics show address 192.168.0.0/24
$ ip tcp_metrics show 192.168.0.0/24
The second command is equivalent to the first. An empty result means no matching cached entry was found at that moment, not that the network is unreachable.
3. Check one address before deleting it
Deleting a single entry changes kernel state and may discard useful learned information. Use the exact address, not a guessed hostname, and inspect it first:
$ DESTINATION='192.168.0.1'
$ ip tcp_metrics show "$DESTINATION"
$ ip route get "$DESTINATION"
The first command should show the matching cached entry if one exists. The second is a separate route lookup that helps confirm the address is the destination you intended; it does not create a TCP metric entry and does not validate that an application is healthy.
Checkpoint
Write down the address you intend to remove and why. If it came from an old log line, a DNS answer, or a copied incident note, re-check it against the current route and service before continuing.
4. Delete one stale destination
When one entry is clearly stale, or you need a targeted retry, delete only that address:
$ sudo ip tcp_metrics delete 192.168.0.1
delete requires an IPv4 or IPv6 address. The manual does not promise a success message, so verify by querying the same address and checking the exit status:
$ ip tcp_metrics show 192.168.0.1
$ printf 'query exit status: %s\n' "$?"
query exit status: 0
A zero query status only means the query ran successfully; it does not by itself distinguish an empty result from a displayed entry, so read the output too. If a new connection later uses the destination, the kernel can learn and cache fresh information again.
There is no inverse command that restores the previous metric values. Recovery is to leave the entry absent and let normal TCP use repopulate it. Keep the old command output if you may need to compare the new behaviour later.
5. Scope a flush before running it
Warning
A flush removes every entry selected by its prefix. Treat it as a service-impacting troubleshooting action: existing connections are not described as being closed by this command, but future connection behaviour may change while the cache relearns values. Take a copy of the read-only evidence first:
$ ip tcp_metrics show 192.168.0.0/24 | tee /tmp/tcp-metrics-before.txt
$ wc -l /tmp/tcp-metrics-before.txt
Only after checking the prefix is correct should you run the flush, normally during a suitable maintenance window:
$ sudo ip tcp_metrics flush 192.168.0.0/24
$ ip tcp_metrics show 192.168.0.0/24
The final query should be empty if no matching entry was recreated immediately. It is not a permanent block: later TCP activity can create fresh entries. The command may need elevated privileges on your host, so do not add sudo to read-only queries merely because a later mutation needs it.
6. Keep IPv4 and IPv6 boundaries clear
An unqualified selector is easy to misread when a host uses both address families. Use an IPv6 prefix when you mean IPv6, and use -6 when flushing all IPv6 entries:
$ ip -6 tcp_metrics show 2001:db8::/32
$ sudo ip -6 tcp_metrics flush all
The documented flush all form removes all entries selected by that command. The -6 example keeps IPv4 entries while clearing IPv6 entries; the reverse is sudo ip -4 tcp_metrics flush all. Both are broad, irreversible cache resets, so prefer a single address or narrow prefix when that is enough.
7. Diagnose an unexpected result
If a query is empty, first check the selector spelling and address family. A cache entry may have expired from the configured capacity and replacement behaviour, or it may simply not have been created yet: the cache is not a durable database, and the manual does not expose a command here for changing its size or forcing an entry to exist.
If a mutation fails with a permission error, stop and inspect the exact command before retrying as root. Elevation can make the operation possible, but it does not make a broad prefix safe. If output differs from the examples, record ip -V and the complete command, because metric fields and formatting are version- and kernel-dependent.
Done means
- Version and syntax confirmed. You checked the installed iproute2 version and subcommand syntax.
- Prefix inspected first. You inspected the relevant prefix before changing the cache.
- Narrow delete used where possible. You used a single-address delete when a narrow reset was sufficient.
- Flushes treated as irreversible. You treated prefix and
allflushes as irreversible troubleshooting actions. - Families kept separate. You kept IPv4 and IPv6 selectors separate and verified the result afterwards.