Back to the map

Module 14 · Network debugging · Lesson 1 of 4

Reading packet captures

When logs disagree, the packets decide. How to capture safely with tcpdump, filter to what matters, and read a capture in Wireshark: handshakes, resets, retransmissions, zero windows and slow responses.

CoreShould-knowMid 13 min Updated Nov 2026

Why it matters

"The client says the server is slow, the server says it answered in 5 ms." Both logs are honest and both are partial. A packet capture shows what actually crossed the wire and when, which settles arguments about who is slow, who closed the connection, whether a request ever arrived and whether loss is involved. It is the most decisive network debugging tool there is, and most engineers never learn to read one.

The idea

A packet capture records copies of packets as they pass a network interface, with precise timestamps. tcpdump captures on servers from the command line; Wireshark (or its terminal sibling tshark) decodes captures into protocols and conversations. You capture where the problem is visible, filter to the traffic you care about, and read the timeline.

Capturing without hurting anything

Capture with a filter so you record only relevant traffic, write to a file rather than printing every packet, and cap the size. A typical server capture: tcpdump -i any -nn -s 0 -w /tmp/api.pcap 'host 10.0.4.17 and tcp port 443' -c 200000. The -nn skips name lookups, -s 0 captures whole packets, and -c stops after a count. Capturing on both ends of a connection, at the same time, is the gold standard: differences between the two views show exactly where packets were lost or delayed. Treat captures as sensitive data, since unencrypted payloads and headers can contain credentials and personal information.

FilterCaptures
host 10.0.4.17Traffic to or from one address
tcp port 5432PostgreSQL traffic
tcp[tcpflags] & (tcp-syn|tcp-rst) != 0Only connection setups and resets: cheap way to watch failures
udp port 53DNS queries and answers
net 10.20.0.0/16 and not port 22A subnet, excluding your own SSH session

Reading a TCP conversation

ClientServerSYN t=0.000SYN-ACK t=0.002ACK + request t=0.002gap: 0.840 sresponse t=0.842FIN / ACKhandshake was 2 ms, so the 840 ms is server think time, not the network
A healthy request: handshake, request, a server think gap, the response, and a graceful close. Each gap's position tells you who was waiting on whom.

Wireshark's "Follow TCP stream" isolates one connection; its time column set to "seconds since previous displayed packet" makes gaps jump out. Ask, for each gap: which side sent the last packet before it? If the client sent a request and the server took 800 ms to answer while the handshake took 2 ms, the network is fine and the server (or something behind it) is slow. If the server answered quickly but the client saw the response late, look for retransmissions or a congested path in between.

Patterns worth recognising

PatternWhat it meansUsually caused by
SYN, SYN, SYN with growing gaps, no replyConnection attempts are not reaching anything that answersFirewall or security group dropping, wrong IP, host down
SYN answered by RSTHost reachable, nothing listening on that portService down or wrong port
Retransmissions and duplicate ACKsPacket loss on the pathCongestion, bad link, overloaded middlebox, MTU black hole for full-size packets
Zero window from the receiverReceiver's buffer is full; the reading application is not keeping upSlow consumer, blocked thread, GC pause
RST in the middle of a session from a middlebox's addressSomething in between dropped the connection's stateLoad balancer or NAT idle timeout shorter than the connection's idle period
ClientHello then immediate alert or RSTTLS negotiation failedProtocol or cipher mismatch, SNI not recognised, certificate rejected
Large gap before the first response byteServer think timeSlow query, lock, dependency call

Encrypted traffic

With TLS you cannot read payloads, but the capture still shows connection setup, the TLS handshake messages (and alerts), timing, sizes and TCP behaviour, which answers most questions. When you must see content, capture at the point where TLS terminates, or have the client export session keys (the SSLKEYLOGFILE environment variable in many TLS libraries) so Wireshark can decrypt in a test environment.

Trade-offs

Captures are the most detailed evidence available, at the cost of being heavy (size, CPU at high rates), sensitive, and narrow (one host's view at a time). Flow logs and metrics are cheap and broad but cannot show individual retransmissions or exact timings. Start broad with metrics to find where to look, then capture narrowly to prove what happened.

In an interview

Describe it as the tie-breaker: "Client logs showed 900 ms, server logs 50 ms. A capture on the server's host showed the request arriving 850 ms after the client's SYN, with the client retransmitting the SYN twice, so connection setup was the problem: the load balancer's backlog was full. Without the capture we would have tuned the wrong service."

Check yourself

A capture on the client shows a request sent at t=0.000, the server's TCP ACK for it at t=0.003, and the HTTP response's first byte at t=1.204, with no retransmissions. Where is the 1.2 seconds being spent?

Reading packet captures · Backplane