How to Trace TCP Autocorking and Coalescing Latency in Linux Using eBPF

Modern Linux kernels employ TCP autocorking to optimize throughput and diminish network interface packet overhead. When an application performs consecutive small write system calls (such as consecutive HTTP headers or chunked streaming payloads), the kernel automatically pauses transmission if at least one unacknowledged packet is already in flight on the wire. This brief pause coalesces subsequent writes into a single maximum segment size (MSS) frame. While highly advantageous for bulk throughput, autocorking can introduce subtle latency penalties in latency-sensitive RPC services. Using eBPF, systems engineers can measure autocorking pauses and tune socket buffering.

Understanding TCP Autocorking Mechanics

Autocorking operates at the socket transmission layer (sysctl net.ipv4.tcp_autocorking). When an application invokes send() or write():

  • If the transmit queue already has data in flight waiting for an ACK, and the new buffer is smaller than the path MSS, the kernel defers packet departure.
  • The kernel releases the coalesced segment immediately when the application sends enough data to fill the MSS or when the outstanding ACK returns from the remote peer.
  • In interactive request-response workloads where clients pipeline multiple small requests, autocorking can inadvertently add up to one full round-trip time (RTT) of queue delay.

Tracing Autocorking Activations with bpftrace

Deploy a targeted eBPF probe targeting the kernel function tcp_push() and its autocorking check inside tcp_should_autocork():

# Install bpftrace on Ubuntu/Debian
sudo apt-get update && sudo apt-get install -y bpftrace linux-headers-$(uname -r)

# Trace TCP autocorking events and socket queuing delays
sudo bpftrace -e '
kprobe:tcp_push {
    $sk = (struct sock *)arg0;
    $flags = arg1;
    $tp = (struct tcp_sock *)$sk;
    if ($flags & 0x40) { // Check for TCP_FLAG_AUTOCORK
        printf("Autocork triggered: PID %d COMM %s PUSH_ONE %d IN_FLIGHT %u
",
               pid, comm, ($flags & 0x40) ? 1 : 0, $tp->packets_out);
        @cork_count[comm] = count();
    }
}'

This script highlights exactly which microservices or reverse proxies are experiencing deferred transmissions due to kernel coalescing logic.

Monitoring Kernel Coalescing Counters

Inspect system-wide packet coalescing and corking statistics using nstat:

# View live TCP coalescing and segmentation counters
nstat -az | grep -E "TCPAutoCorking|TCPCoalesce"

# Sample output:
# TcpExtTCPAutoCorking             31845
# TcpExtTCPCoalesce               142980

A disproportionately high TCPAutoCorking counter confirms that your network stack is actively buffering consecutive small writes.

Disabling or Tuning Autocorking for Low-Latency Applications

If eBPF tracing reveals that autocorking is increasing p99 latency on real-time microservice communication:

  1. Application-Level Control: Use the TCP_NODELAY socket option to disable Nagle’s algorithm, and explicitly flush buffers using TCP_CORK only around large file transfers.
  2. System-Wide Parameter Tuning: In environments dedicated purely to low-latency financial trading or interactive gaming backends, disable system-wide autocorking:
    # Temporarily disable TCP autocorking
    sudo sysctl -w net.ipv4.tcp_autocorking=0
    
    # Persist configuration across reboots
    echo "net.ipv4.tcp_autocorking = 0" | sudo tee -a /etc/sysctl.d/99-latency.conf
    sudo sysctl -p /etc/sysctl.d/99-latency.conf
  3. Deploy Fair Queueing (FQ): The fq qdisc pairs cleanly with autocorking, pacing packets at the hardware layer and smoothing out packet bursts.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.