tcpflow: tcpdump for People Who Want to Read the Conversation

2026-05-25

You know the drill. Something's broken between your service and an upstream API. You reach for tcpdump, capture a pcap, then squint at hex dumps or load it into Wireshark just to read a few HTTP requests. There's a better tool that's been sitting in Debian since the early 2000s: tcpflow, written by Jeremy Elson and now maintained by Simson Garfinkel (yes, that one).

tcpflow reassembles TCP streams in real time and writes each flow to its own file. No pcap reading step. No Wireshark. Just one file per direction of each connection, containing exactly the bytes that flowed across it.

sudo tcpflow -i eth0 port 80

That spits out files like 192.168.010.005.45122-093.184.216.034.00080 (client→server) and the reverse. Open them with less. You're reading the HTTP request and response directly, in order, with retransmissions and out-of-order packets already reassembled for you.

The killer flag is -c, which dumps reassembled flows straight to stdout with colorized client/server tagging:

sudo tcpflow -c -i lo port 6379
# watch your Redis traffic live, RESP protocol and all

sudo tcpflow -c -i any port 5432
# every Postgres wire-protocol exchange, tagged by direction

For HTTP debugging, combine it with the BPF filter and a quick grep:

sudo tcpflow -c -i any 'port 8080' | grep -E '^(GET|POST|PUT|HTTP/)'

Want only the headers of every request hitting your dev server? -e http turns on the HTTP scanner, which extracts requests, responses, and even decompresses gzipped bodies into separate files:

sudo tcpflow -i any -e http port 8080
# produces *.HTTP and *.HTTPBODY files, decompressed

Other scanners worth knowing: -e netviz generates a GraphViz visualization of who-talked-to-whom, -e tcpdemux handles arbitrary protocols, and -e md5 hashes each flow so you can spot duplicates.

The -r file.pcap mode reads existing captures, so you can keep using tcpdump for collection on a production box (smaller, more universal) and process the pcap with tcpflow on your laptop:

ssh prod 'sudo tcpdump -i any -w - port 443' > capture.pcap
tcpflow -r capture.pcap -o /tmp/flows

Where it beats tcpdump: tcpdump shows you packets. tcpflow shows you conversations. If you've ever caught yourself manually following a TCP stream in Wireshark just to read what was actually sent, that's the entire workflow tcpflow replaces. For plaintext protocols (HTTP, Redis, Postgres, SMTP, IRC, gRPC over h2c, custom TCP services) it's the fastest path from "something's weird on the wire" to "oh, the client is sending a malformed Content-Length."

Where it loses: TLS. tcpflow gives you the encrypted bytes, which are useless. For that you need SSLKEYLOGFILE + Wireshark, or an intercepting proxy like mitmproxy. tcpflow is for plaintext on the wire.

One more gem: -a turns on all scanners at once, and -S enable_post_processing=true lets each scanner do its thing as flows close, so you get fully decoded artifacts when the connection ends rather than partial dumps.

Install: apt install tcpflow, brew install tcpflow, or build from the github.com/simsong/tcpflow tarball. It's a single static binary with libpcap as the only real dependency.

Key Takeaway: When you care about what was said and not which packet said it, tcpflow gives you per-flow files of reassembled bytes — no pcap dance required.

All newsletters