▦Packet Report

Measure TCP retransmissions without mistaking them for packet loss

Use Wireshark and TShark to count TCP retransmissions, calculate a directional share, and check sequence numbers, recovery timing and capture quality.

Packet Report Editorial Team · 7 min read

To measure TCP retransmissions, count packets matching Wireshark’s three retransmission labels, then divide by a clearly defined packet population from the same stream, direction and time window. Validate several matches against sequence numbers and ACKs before treating the result as evidence of a network problem.

The result is an observed retransmission share, not an end-to-end packet-loss percentage. These filters measure TCP, not Wi-Fi link-layer retries or retries in other protocols.

1. Check the capture before counting

Use only traffic you own or are authorized to inspect. Start with the original capture, ideally including the TCP handshake and both directions of the connection.

Check these conditions:

  • Capture location: Record whether the file came from the sender, receiver or an intermediate observation point. Wireshark’s classifications can differ with capture location and available packet history.
  • Capture drops: Check the status bar for a Dropped count. That means the capture mechanism missed packets; it is not a count of packets lost on the network. An absent count does not establish that every packet was captured: many capture formats do not retain drop counts.
  • Mirroring capacity: A busy switch mirror can lose packets before they reach the capture host. Check its configuration and capacity if you are using one.
  • Host offloads: Endpoint captures can contain unexpectedly large segments or unfinished checksums. Do not treat those artifacts as proof of loss, or compare their packet counts directly with a wire capture without checking segmentation differences.

These limitations are described in Wireshark’s documentation on TCP analysis, the status bar, Ethernet capture setup and offloading.

In Wireshark’s TCP protocol preferences, ensure Analyze TCP sequence numbers is enabled. The retransmission fields are generated analysis labels, not flags transmitted in the TCP header.

2. Find the retransmission candidates

Apply this display filter, not a capture filter:

tcp.analysis.retransmission ||
tcp.analysis.fast_retransmission ||
tcp.analysis.spurious_retransmission

Include all three fields: Wireshark’s fast and spurious classifications can supersede the generic retransmission classification. Filtering only on tcp.analysis.retransmission can therefore miss other retransmission candidates. The TCP analysis guide documents that precedence, and the TCP field reference identifies these fields as suspected retransmissions.

Label What Wireshark inferred What to check next
Retransmission The sequence number falls behind its next expected sequence number Earlier transmissions of that byte range and reverse-direction ACKs
Fast retransmission Sequence, ACK and timing evidence fits its fast-retransmission heuristic Duplicate ACKs or SACK information before the repeat
Spurious retransmission The segment’s data is already covered by an ACK seen in the reverse direction ACK timing, delayed delivery and capture ordering

Do not add duplicate ACKs or out-of-order packets to the retransmission numerator. Duplicate ACKs are feedback, not resent data. They can result from loss, reordering or packet replication, as RFC 5681 explains.

3. Calculate a directional retransmission share

Choose one TCP conversation. Select a packet and find its tcp.stream value in the TCP details. The examples below use stream 7; substitute the value from your file.

For a data-packet metric, first count all observed packets carrying TCP payload in that stream:

tcp.stream == 7 && tcp.len > 0

Read the Displayed packet count in the status bar. This is the denominator, D. It includes original transmissions and retransmissions, but excludes packets with no TCP payload, including pure ACKs and payload-free SYNs or FINs.

Next count payload-bearing retransmission candidates:

tcp.stream == 7 && tcp.len > 0 &&
(tcp.analysis.retransmission ||
 tcp.analysis.fast_retransmission ||
 tcp.analysis.spurious_retransmission)

This displayed count is the numerator, R. Each matching packet counts once, even if multiple fields match.

Calculate:

Observed data-packet retransmission share (%) = 100 × R / D

Measure each direction separately. For example, if the sender being measured uses source port 443 in this stream, append this condition to both filters:

&& tcp.srcport == 443

Confirm the sender from the actual endpoints; a port number alone does not establish its role. If source port cannot distinguish the directions, use the sender’s source-address field instead (ip.src for IPv4 or ipv6.src for IPv6).

For a fixed interval, also append the same time condition to both filters:

&& frame.time_relative >= 10 && frame.time_relative < 70

That selects a 60-second window beginning 10 seconds into the file. Keep the full capture loaded so earlier packets remain available to sequence analysis.

As an illustrative calculation, 24 matching data packets out of 2,400 observed data packets in one direction gives 1.0%. Report it as “1.0% of observed data packets were labelled as retransmissions,” not “1.0% packet loss.” If D is zero, the share is undefined.

Wireshark documents its displayed packet counter in the status-bar guide. Avoid using the status bar’s percentage of the entire file as your directional rate: its denominator is not necessarily your selected data-packet population.

4. Export repeatable measurements with TShark

For repeated analysis, export all payload-bearing packets in the chosen stream, including the three analysis fields. This command uses POSIX-shell syntax:

tshark -2 -n -r authorized.pcapng \
-Y 'tcp.stream == 7 && tcp.len > 0' \
-T fields -E header=y -E separator=, -E quote=d \
-e frame.number \
-e frame.time_relative \
-e tcp.srcport \
-e tcp.dstport \
-e tcp.seq \
-e tcp.len \
-e tcp.analysis.retransmission \
-e tcp.analysis.fast_retransmission \
-e tcp.analysis.spurious_retransmission \
  > tcp-data.csv

Here, -r reads the saved capture, -Y applies a display filter, -2 enables two-pass analysis, and -T fields exports the requested fields. These options are documented in the TShark manual.

In a spreadsheet or analysis program:

  1. Select the sender direction and time window. If the two endpoints use the same port number, restrict the direction using a source-address condition in -Y before exporting; the example CSV does not contain addresses.
  2. Count data rows, excluding the header, to obtain D.
  3. Mark a row as a retransmission candidate if any of its three retransmission fields is nonempty. These are label fields, so do not assume they export as numeric 1 values.
  4. Count marked rows to obtain R, then calculate 100 × R / D.

You can also calculate a labelled payload-byte share: divide the sum of tcp.len in marked rows by the sum of tcp.len in all selected rows. This weights larger packets more heavily, but it is not an exact count of unique bytes resent: a labelled segment can overlap previously sent data only partly. TCP sequence numbers identify bytes, not packet identities, as specified in RFC 9293.

Keep the Wireshark/TShark version and TCP analysis preferences consistent across comparisons, including enabling sequence-number analysis in TShark’s configuration. The export omits payloads and addresses, but timing and port metadata can still be sensitive.

5. Verify byte ranges and recovery timing

Remove the retransmission-only filter and inspect the full stream around several matches, particularly those coinciding with a stall.

For each candidate, check:

  • Sequence range: Compare tcp.seq and tcp.len with earlier data in the same direction. For ordinary data without SYN or FIN, the byte range is [seq, seq + len), accounting for wraparound at 2³².
  • Receiver feedback: Look at reverse-direction tcp.ack and any SACK blocks. Does the cumulative ACK stop advancing before the repeat, then advance afterward?
  • Timing: If the original transmission is visible, subtract its timestamp from the repeated transmission’s timestamp. Separately measure when an ACK advances past the affected range.

RFC 9293 defines byte sequencing, sequence-number wraparound and cumulative acknowledgments.

For example, in a hypothetical trace, data at Seq=1001, Len=1000 appears again 240 ms later, followed by an ACK of 2001. That supports a repeated byte range and an observed 240 ms resend interval. It does not establish a 240 ms application delay or reveal where a packet disappeared.

A generic retransmission label alone does not prove the sender’s retransmission timer expired. Wireshark classifies from observed sequence history and heuristics, and its documentation explicitly discusses ambiguous retransmission versus out-of-order interpretations.

What to put in the measurement report

Record the capture point, capture quality concerns, tool version, stream and direction, time window, R, D, calculated share, and a few verified byte-range examples. State whether spurious retransmissions were included; this workflow includes them.

If the first transmission was lost before your observation point, the capture may contain only the later copy. Conversely, missing ACKs or duplicated observations can distort automatic interpretation. A single capture therefore cannot convert retransmission labels into a reliable path-loss percentage or identify the failing link.

For performance diagnosis, pair the count with TCP RTT measurements and the timing of the actual stall. A small retransmission share concentrated during one request can matter more to that request than a larger share elsewhere in the capture.