Demonstrations of tcpretrans, the Linux ftrace version. Tracing TCP retransmits on a busy server: # ./tcpretrans TIME PID LADDR:LPORT -- RADDR:RPORT STATE 05:16:44 3375 10.150.18.225:53874 R> 10.105.152.3:6001 ESTABLISHED 05:16:44 3375 10.150.18.225:53874 R> 10.105.152.3:6001 ESTABLISHED 05:16:54 4028 10.150.18.225:6002 R> 10.150.30.249:1710 ESTABLISHED 05:16:54 4028 10.150.18.225:6002 R> 10.150.30.249:1710 ESTABLISHED 05:16:54 4028 10.150.18.225:6002 R> 10.150.30.249:1710 ESTABLISHED 05:16:54 4028 10.150.18.225:6002 R> 10.150.30.249:1710 ESTABLISHED 05:16:54 4028 10.150.18.225:6002 R> 10.150.30.249:1710 ESTABLISHED 05:16:54 4028 10.150.18.225:6002 R> 10.150.30.249:1710 ESTABLISHED 05:16:54 4028 10.150.18.225:6002 R> 10.150.30.249:1710 ESTABLISHED 05:16:55 0 10.150.18.225:47115 R> 10.71.171.158:6001 ESTABLISHED 05:16:58 0 10.150.18.225:44388 R> 10.103.130.120:6001 ESTABLISHED 05:16:58 0 10.150.18.225:44388 R> 10.103.130.120:6001 ESTABLISHED 05:16:58 0 10.150.18.225:44388 R> 10.103.130.120:6001 ESTABLISHED 05:16:59 0 10.150.18.225:56086 R> 10.150.32.107:6001 ESTABLISHED 05:16:59 0 10.150.18.225:56086 R> 10.150.32.107:6001 ESTABLISHED ^C Ending tracing... This shows TCP retransmits by dynamically tracing the kernel function that does the retransmit. This is a low overhead approach. The PID may or may not make sense: it's showing the PID that was on-CPU, however, retransmits are often timer-based, where it's the kernel that is on-CPU. The STATE column shows the TCP state for the socket performing the retransmit. The "--" column is the packet type. "R>" for retransmit. Kernel stack traces can be included with -s, which may show the type of retransmit: # ./tcpretrans -s TIME PID LADDR:LPORT -- RADDR:RPORT STATE 06:21:10 19516 10.144.107.151:22 R> 10.13.106.251:32167 ESTABLISHED => tcp_fastretrans_alert => tcp_ack => tcp_rcv_established => tcp_v4_do_rcv => tcp_v4_rcv => ip_local_deliver_finish => ip_local_deliver => ip_rcv_finish => ip_rcv => __netif_receive_skb => netif_receive_skb => handle_incoming_queue => xennet_poll => net_rx_action => __do_softirq => call_softirq => do_softirq => irq_exit => xen_evtchn_do_upcall => xen_do_hypervisor_callback This looks like a fast retransmit (inclusion of tcp_fastretrans_alert(), and being based on receiving an ACK, rather than a timer). The -l option will include TCP tail loss probe events (TLP; see http://lwn.net/Articles/542642/). Eg: # ./tcpretrans -l TIME PID LADDR:LPORT -- RADDR:RPORT STATE 21:56:06 0 10.100.155.200:22 R> 10.10.237.72:18554 LAST_ACK 21:56:08 0 10.100.155.200:22 R> 10.10.237.72:18554 LAST_ACK 21:56:10 16452 10.100.155.200:22 R> 10.10.237.72:18554 LAST_ACK 21:56:10 0 10.100.155.200:22 L> 10.10.237.72:46408 LAST_ACK 21:56:10 0 10.100.155.200:22 R> 10.10.237.72:46408 LAST_ACK 21:56:12 0 10.100.155.200:22 R> 10.10.237.72:46408 LAST_ACK 21:56:13 0 10.100.155.200:22 R> 10.10.237.72:46408 LAST_ACK ^C Ending tracing... Look for "L>" in the type column ("--") for TLP events. Use -h to print the USAGE message: # ./tcpretrans -h USAGE: tcpretrans [-hs] -h # help message -s # print stack traces eg, tcpretrans # trace TCP retransmits