Why you can't parallelize tshark, and what I did instead
Follow-up to my post a couple of weeks ago about a 2.5 GB PCAP that took 6-7 hours to process. Streaming tshark's output into Go got it to 70 minutes, but it was still single-threaded. The most common response here was: why not just add goroutines? Turns out you can't, and the reason is that tshark's dissection is linear state. What it reads in one packet determines how it decodes the next — TCP reassembly, connection tracking, anything under tcp.analysis.* reads and updates shared conversation tables as it goes. Strict ordering isn't a design choice, it's what dissection requires. Goroutines on the consuming side don't help because the bottleneck was never there. So the concurrency has to happen before tshark sees the file. Not by splitting on size — a TCP stream cut mid-conversation loses the state the dissector needs — but by session, so each chunk holds complete conversations and nothing crosses a boundary. Then N tshark processes run in parallel. The detour: I was using PcapSplitter from PcapPlusPlus in connection mode, which holds one output file open per flow. At 95-125 flows it started producing corrupted output. Two distinct failure signatures, reproduced on master and v25.05, on both pcapng and legacy pcap. pcapfix said the source was clean. Reimplemented the split in-process with gopacket and it went away. Honest ending: splitting only triggers above 100k packets, and 3 of the 57 files this pipeline actually handles cross that threshold. Full writeup: robinhayer.dev/concurrency-without-a-parallel-parser